[Ruby] ブロックとProcの違いを解説

rubyは、業務でひたすら書いているだけで、きちんとRubyの技術書を読んでなかったなと

最近思い、パーフェクトRubyを読み始めました。

その時に、ブロック・Procの違いがようやく理解出来たので、備忘録として書いています。

 

ブロックとは

do ~ end または、{~}で表されるもの。

下のコードで言うと、{p "hoge"}  or do p "hoge" end の部分です。

ブロックは、yieldで評価することができる。

オブジェクトではない、ただの処理の集まり。

 

Procとは

関数(処理)をオブジェクトとして表現したもの。

ブロックと関連づけて書くと、ブロックをオブジェクト化したもの

メソッドの引数に&を付け加えることによって、渡ってきたブロックをProcオブジェクトとして扱うことができる。

下の例では、{p "hoge"}と言うブロックを、with_blockメソッドに渡しているが、&によって、{p "hoge"}をProcオブジェクトとして、扱うことができる。

&blockのことを、ブロック引数と言う。

 

to_proc

self に対応する Proc オブジェクトを返す。

生成される Proc オブジェクトを呼びだす(Proc#call)と、 Proc#callの第一引数をレシーバとして、 self という名前のメソッドを 残りの引数を渡して呼びだす。

 

ブロックとProcの違いがわかったところで、下のコードは一体どう言うことだと疑問になりました。

よくこのようなコードを書きますが、一体どう言うことやってなったんで、調べてみました。

上記のコードは、冗長化すると、以下のコードのようにも表せます。

上でも書いたように、&を使うことによって、引数にProcオブジェクトを使えるようになります。

で、ここで出てくるのが、to_procメソッドです。

メソッドオブジェクトは、to_procメソッドをデフォルトで持っているので、以下のように表すことができる。

つまり、

map(&:to_s)&:to_s内では、to_sメソッドを呼び出すProcオブジェクトを生成している。(Procオブジェクトの中で、引数に対して一個づつ.to_sの処理を行なっている。)

=> つまり、&:to_sすることによって、以下のように処理を走らせている。

 

まとめ

  • &を使うことによって、Procオブジェクトとして扱うことができる
    • ブロック引数という
  • ブロック引数には、Procオブジェクトだけでなく、to_procメソッドをもつオブジェクトも渡すことができる(主に、メソッドオブジェクト)
  • メソッドオブジェクトは、to_procメソッドを持っている

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA