- ベストアンサー
Rubyのブロックについて
こんにちは、いつもお世話になってます。 本を読んでいくうちに、メソッドの引数の最後に&をつけたものとyieldを書いたものの違いがほとんどないように思えました。 この違いを考えてみたらyieldは引数が持てることくらいしか思いつかないのですがそう考えていいですか? そもそも基本から両者を間違って理解していたら申し訳ございません。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
#1の人の補足修正ですが、yieldを使うときに、ブロックがあるか無いかは、 if block_given? __yield(1) end で判断します。 一番大きいのは、&で受け取ると、手続きオブジェクトとしてハンドリングできるので、別のメソッドに渡せることです。 def a(&p) __puts "call a" __b(&p) end def b(&p) __puts "call b" __p.call("call here") end a { |x| puts "proc "+x } 引数ももちろん渡せますので、機能的にはyieldのメリットがないので廃止の案もあったようです(速度面のメリットはあり)。
その他の回答 (1)
- lingring
- ベストアンサー率50% (1/2)
違いは少なくとも3つあるようです。 1. ブロック無しで使われたときに、&をつけた引数にはnilが代入されます。 def hoge &block if block then 'A' else 'B' end end hoge #==> 'B' 一方、yield では、エラーがおきます。 def hoge if yield then 'A' else 'B' end end hoge # ==> LocalJumpError: no block given 2. 実行時速度がyieldを使ったときの方が&を使ったときよりも速いようです。 3. &を使ったときは、callメソッドを呼ばなければいけません。 def hoge &block block.call(1) end hoge {|i|+2} #==> 3 一方、yieldはそのまま使えます。 def hoge yield(1) end hoge {|i|+2} #==> 3 まとめると、ブロックを随意的にしたいときや、ブロック引数をとることをメソッド定義の1行目で明示したいときは&を使い、そうでなく、速さにこだわりたいときはyieldを使うべきのようです。
お礼
ありがとうございます。 ブロックは難しくて自分で実装できるようになるまでは時間がかかりそうですが頑張ろうと思います。 ふと疑問なんですがなんで関数名とかよくfooとかhogeを使うんでしょうか? 本見るたびに疑問に思ってました
お礼
なるほど、単純にcallの後に引数を付ければ良かったのですね。 本のほうではyieldの説明のほうが詳しく書いてあったような気がしたんですが。。 廃止案もあったなんてびっくりです。 ありがとうございました。