ブロックの代わりに(&: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を考えた人になってみる


うーん、理解しきるのが難しい、、、