2012-03-16 4 views
3

にブロック対括弧を使用する際に、 RubyはJavaの、PHP、Cなどのような他のオブジェクトorieintedの言語に非常に似ているように見えるは混乱表面でのRuby

しかし、物事は我々がバンプを開始したときに少し奇妙な取得ブロックに変換する。

例えば、これは

(0...8).max() 
=> 7 

に動作しますが、これは

(0...8).map(puts "hello world") 
hello world 
ArgumentError: wrong number of arguments(1 for 0) 

Apprantly、マップ・メソッドは、引数を取るが、ブロックを取るしませんしませんので、{}()を交換し、エラーを修正渡します。

(0...8).map{puts "hello world"} 
hello world 
hello world 
hello world 
hello world 
hello world 
hello world 
hello world 
hello world 
=> [nil, nil, nil, nil, nil, nil, nil, nil] 

そして、いくつかの方法は、両方を取るべきである - ブロックを&引数

8.downto(1){puts "hello world"} 
hello world 
hello world 
hello world 
hello world 
hello world 
hello world 
hello world 
hello world 
=> 8 

は私が持っている問題は、私が示された手法に(){}またはその両方を使用してする必要がある場合に混乱です。どのような基準で決定されるのですか?

  • それは方法ごと&に固定されている私は持っている方法は、(ブロックまたはのparams)を取るもの覚えていますか?
  • またはメソッドがブロック{}かのparams ()をとる場合には、決めますそれに基づいて他の論理的な推論はありますか?

私はそれは方法のAPIで文書化されなければならない

答えて

6

メソッド呼び出し後のかっこは、実際はオプションです。

(0...8).map{puts "hello world"}(0...8).map() {puts "hello world"}

に相当しますので、あなたは本当にそれらを置き換えるものではありません。

ブロックの受け入れが完全方法次第である

、それらはメソッド宣言に指定することができる:ブロックがメソッド内からの変数としてアクセスすること、および呼び出すことを可能にする

def method(param, &block) 
    block.call 
end 

例えばblock.callを介して。

彼らはまた、yieldキーワードを使用することによって暗黙的に使用することができます。

def method(param) 
    yield 
end 

だから、あなたが受け入れられたりされていないものを確認するためにAPIのドキュメンテーションを参照する必要があります。

2

を理解してください。

引数を受け付ける方法がある場合、ブロックは、通常、任意である - 例えば - 方法の動作方法「を精緻化」するために使用されるような場合にHash.newは、引数(デフォルトのハッシュ値)とキー値の初期化中にスマートな処理を行うために使用されるブロックを受け入れることができます。しかし、ブロックを必要とするメソッドの大部分は引数を受け付けません。 Array#selectまたはArray#map

2

括弧を使用して、引数を関数に渡します。これは常にコンマで区切られたオブジェクトのリストです。それらは関数の結果かもしれませんが、必要はありません。それらの結果である関数は常に1回だけ正確に呼び出されます。

例:

x = Array.new 
=> [] 
x.push(2) 
=> [2] 
x.push(7.modulo(4)) 
=> [2,3] 

あなたはメソッドに機能的な振る舞いを渡すためにブロックを使用しています。これらの関数は、通常、多くの異なる引数または一定の時間で呼び出されるようになっています。 puts "hello world"は何かを印刷する関数ですが、nilしか返しません。だから、関数の引数としてそれを使うことは決して決してありませんが(通常はその関数にnilを渡すでしょうが)、関数をブロックとして渡して複数回呼び出すことができます。

ほとんどの場合、ブロックに関数を渡して引数を使用することが必要なので、呼び出されるたびに実際には異なる処理が行われます。

例:

(0..8).each{ |number| 
    if number.odd? 
    puts "#{number} is odd" 
    end 
} 
=> 1 is odd 
=> 3 is odd 
=> 5 is odd 
=> 7 is odd 
=> => 0..8