要旨
user_id = params[:user_id].tap { |uid| p User.find(uid).name } contents = Content.made_by(user_id) ...
詳細
Object#tap
は self
自身を返す。なので、ちょっと中身を覗いたりするのに便利。上記の例で言えば、 uid
に self
すなわち params[:user_id]
が入った状態でブロックが呼ばれる。
user_id = params[:user_id].tap { |uid| p User.find(uid).name } contents = Content.made_by(user_id) ...
Object#tap
は self
自身を返す。なので、ちょっと中身を覗いたりするのに便利。上記の例で言えば、 uid
に self
すなわち params[:user_id]
が入った状態でブロックが呼ばれる。
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
のように呼べば良い。
変数に対してメソッドチェインの途中で String#capitalize
等の String
クラスのメソッドが挟まる場合、変数の初期段階で Object#to_s
を読んでおくと不用意に Nil#some_method
が出てしまうことを回避できる。
Object#to_s
は、 Object
が nil
の場合、 ''
を返す。
Rubyでは(Rubyに限らないが)、メソッドチェインを使用して、複数のメソッドを連続で呼ぶ事がよくある。この時、 String#capitalize
等のString
クラスのメソッドをチェインする場合、チェイン途中に nil
が居ると都合が悪い。つまり、 Nil#some_method
を呼び出そうとして、 NoMethodError
が出てしまうのである。
これを避けるため、変数に対して希望のメソッドを呼ぶ前に、 Object#to_s
を読んでおくと、 Object
が nil
だった場合に ''
が返るため、 Nil#some_method
を呼び出してしまって NoMethodError
にぶつかってしまうことを避けられる。
下記の例を考えてみる。
params[:given_name].capitalize
params[:given_name]
にString
が入っていれば何の問題も無いが、nil
の場合は前述の通り NoMethodError
になってしまう。これはこのように書き換えるのがおすすめである。
params[:given_name].to_s.capitalize
注意
目的に応じて、本当に Object#to_s
して良いかは各自で判断する必要がある。場合によっては、 NoMethodError
で落とした方が間違いに気づけて良い場合もある。
「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
でなくても何でも良い。
%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
ブラウザでRubyが動く時代が来る…のか?
less +F
も tail -f
も、基本的な動作は同じ。
その動作は、監視対象のファイルに追加書き込みがあった場合、その内容を随時標準出力(ほとんどの場合画面上)に出力し続けるというもの。
ただし、 less +F
は通常の less
と変わらない動作モードへ変更することができる。その間は下記のような移動が可能。
j
(下)k
(上)g
(ファイル先頭)G
(ファイル末尾)例えば、 production.log
を監視する場合を考える。このファイルに書き込みがあった際、その内容を画面上に表示したい。
この時は、 tail -f
が使用できるが、同様に less +F
も使用できる。また前述の通り、less +F
の使用中に Ctl + C
を押すと、通常のless
と同じ状態になり、行の戻り送りやファイル先頭末尾への移動が可能になる。
この状態で F
(Shift + f
) を入力すると、再度 less +F
したのと同じ状態になり、ファイルへの新しい書き込みを待ち受ける。