ブロックの代わりに(&:hoge)を使ってみる
榊間です。
明日ある大学のテストに怯えながら書いてます、、、
今日はrubyの仕組み的な話です。
(&:)ってなに....
この前作業してたら、
Article.where(user: current_user).map{|e| e.id}
みたいな記述を、
Article.where(user: current_user).map(&:id)
に直してもらいました。なぜこんな風に書けるのか、、、
Article.where(user: current_user).map{|e| e.id}をArticle.where(user: current_user).map(&:id)に変化させていきます
Kernelのsendメソッド使います。第1引数にシンボル化したレシーバのメソッドをとり、第2引数以降はレシーバの引数をとります。
Article.where(user: current_user).map { |e| e.send(:id) }
それから&lambdaを使って、ブロックをオブジェクトにします。ブロックをmapの引数として渡せるようになります。
Article.where(user: current_user).map(&lambda { |e| e.send(:id) })
作ったオブジェクトを、メソッドとして定義します。(シンボル化したレシーバのメソッドをオブジェクトの変換するメソッド)
class Symbol def to_proc lambda { |e| e.send(:id) } end end Article.where(user: current_user).map(&:id.to_proc)
&を設置しているのでrubyはオブジェクトを&の後に要求しますが、シンボルじゃんってなって、to_procメソッドを勝手に送ります。
class Symbol def to_proc lambda { |e| e.send(:id) } end end Article.where(user: current_user).map(&:id)
実際は
class Symbol def to_proc Proc.new { |*args| args.shift.__send__(self, *args) } end end
が記述されているので、Article.where(user: current_user).map(&:id)の記述だけで済むみたいですね、、、
参考にしたのはここRubyのSymbol#to_procを考えた人になってみる
うーん、理解しきるのが難しい、、、