dogwood008の開発メモ!

最近のマイブームは機械学習, Ruby on Rails。中でも機械学習を使った金融商品の自動取引に興味があります。

【Ruby】文字列をメソッド名として実行する

要旨

method('some_method').call(arg1, arg2)

詳細

methodに String, Symbol を渡すと、 Method オブジェクトが返る。これに対して Method#call を呼ぶと、そのメソッドを実際に呼ぶ事ができる。

呼びたいメソッドに引数を渡したい場合、 call(arg1, arg2, ...) のように call に引数を渡してやれば良い。

また、特定のClassのインスタンスメソッドを呼びたいときは、 some_instance.method(:method_name).call のように呼べば良い。

クラスメソッドの場合は、 Class.method(:method_name).call のように呼べば良い。

参考

docs.ruby-lang.org

docs.ruby-lang.org

【Ruby】Nillableな変数を引数として受け得るなら、Object#to_sしておけば色々と便利

概要

変数に対してメソッドチェインの途中で String#capitalize 等の String クラスのメソッドが挟まる場合、変数の初期段階で Object#to_s を読んでおくと不用意に Nil#some_method が出てしまうことを回避できる。

詳細

Object#to_s は、 Objectnil の場合、 '' を返す。

Rubyでは(Rubyに限らないが)、メソッドチェインを使用して、複数のメソッドを連続で呼ぶ事がよくある。この時、 String#capitalize 等のStringクラスのメソッドをチェインする場合、チェイン途中に nil が居ると都合が悪い。つまり、 Nil#some_method を呼び出そうとして、 NoMethodError が出てしまうのである。

これを避けるため、変数に対して希望のメソッドを呼ぶ前に、 Object#to_s を読んでおくと、 Objectnil だった場合に '' が返るため、 Nil#some_method を呼び出してしまって NoMethodError にぶつかってしまうことを避けられる。

具体例

下記の例を考えてみる。

params[:given_name].capitalize

params[:given_name]Stringが入っていれば何の問題も無いが、nil の場合は前述の通り NoMethodError になってしまう。これはこのように書き換えるのがおすすめである。

params[:given_name].to_s.capitalize

注意

目的に応じて、本当に Object#to_s して良いかは各自で判断する必要がある。場合によっては、 NoMethodError で落とした方が間違いに気づけて良い場合もある。

【Ruby】Array#filter と Array#map を組み合わせて使うなら、 Array#filter_map というメソッドがあるよ

要旨

「3の倍数と3のつく数字」だけを String に変換した Array<String> を得る方法:

(1..100).filter_map { |i|
  i.to_s if i % 3 == 0 || i.to_s.include?('3')
}.to_a
# => ["3", "6", "9", "12", "13", "15", "18",
# "21", "23", "24", "27", "30", "31", "32",
# "33", "34", "35", "36", "37", "38", "39",
# "42", "43", "45", "48", "51", "53", "54",
# "57", "60", "63", "66", "69", "72", "73",
# "75", "78", "81", "83", "84", "87", "90",
# "93", "96", "99"]

詳細

正確には Array#filter_map ではなく Enumerable#filter_map なので、EnumerableなオブジェクトならArrayでなくても何でも良い。

参考

docs.ruby-lang.org

techtechmedia.com

k-koh.hatenablog.com

【Ruby, Active Support】Array#include?(Object) もあるが、 Object#in?(Array) もある

概要

%w[a b c d e].include?('c') == 'c'.in?(%w[a b c d e])

詳細

Array#include? Ruby 標準のメソッド。一方、 Object#in? は Active Supportを require すると使えるようになるメソッド。

ただし、 Active Support全体を require する必要はなく、下記の部分のみで良い。必要なファイルのみに抑えて、リソースを節約しよう。

require 'active_support/core_ext/object/inclusion'

定義

L7-8では、懐かしのキャラクターが登場してびっくりした。みゆきさんはどこ…?

characters = ["Konata", "Kagami", "Tsukasa"]
"Konata".in?(characters) # => true

github.com

参考

railsguides.jp

【Shell】tail -f で随時書き込まれる内容を表示できるが、less +F でもできる

要旨

less +Ftail -f も、基本的な動作は同じ。

その動作は、監視対象のファイルに追加書き込みがあった場合、その内容を随時標準出力(ほとんどの場合画面上)に出力し続けるというもの。

ただし、 less +F は通常の less と変わらない動作モードへ変更することができる。その間は下記のような移動が可能。

  • j(下)
  • k(上)
  • g(ファイル先頭)
  • G (ファイル末尾)

詳細

例えば、 production.logを監視する場合を考える。このファイルに書き込みがあった際、その内容を画面上に表示したい。

この時は、 tail -f が使用できるが、同様に less +F も使用できる。また前述の通り、less +Fの使用中に Ctl + C を押すと、通常のless と同じ状態になり、行の戻り送りやファイル先頭末尾への移動が可能になる。

この状態で FShift + f) を入力すると、再度 less +F したのと同じ状態になり、ファイルへの新しい書き込みを待ち受ける。

参考

linuxjm.osdn.jp

www.brianstorti.com

genzouw.com

devlights.hatenablog.com

tech.withsin.net