プログラミング的なSomething

プログラミング的なSomething

ITエンジニア(?)目線で生活・自転車・トレーニング話を綴ります

ProcとSymbol#to_procに関して調べた

昨日の日記で宿題にしてたto_procメソッドに関して

CodeIQに出題されている問題をやってみた その②

CodeIQで解答のある問題を使わせていただき、プログラムへの理解を深めております。 そこでto_procの処理につまずきました。

そもそもProcってなんだっけ

Procは、ブロックをオブジェクトとして扱うための道具です。受け取ったブロックを変数に代入したり、他のメソッドの呼び出し引数にすることができます。

Procの作り方

仮引数リストの最後に&で修飾された引数を配置すると、この引数に、呼び出し側のブロックを表すProcオブジェクトされます。

class SleepPerson
  def register_handler(&handler) #=>引数としてとったブロックを@event_handlerへ格納
    @event_handler = handler
  end

  def wake_up!
    @event_handler.call Time.now, "Woke up"
  end
end

john = SleepPerson.new
john.register_handler { | time, message| p [time, message] } #=>ブロックを引数にできる!
john.wake_up! #=>[2014-01-11 14:08:53 +0900, "Woke up"]

はじめてのRubyの写経なんですが、wake_up!メソッドに3値目を足したり、john.register_handlerのブロックの値を少なくしたりすると動作がイメージしやすかった。

話を戻してto_procのおはなし

もともとは、以下のようなメソッドが原因で沼にはまったのでした。

method.inject(&:&)

これ、mapのチェーンメソッドなので&:&はブロックじゃないといけないのです。&:&がブロックということは、:&はProcオブジェクトであることが期待されるので、暗黙的にto_procメソッドが呼ばれます。これがSymbol#to_procの正体です。

まとめ

  • Procはブロックをオブジェクト化する機構(おさらい)
  • 引数に&をつけるとブロックを期待されるので、その場合には暗黙のto_procが入る

参考