0

Rubyを学習しているときに、各メソッドのこれらの使用法の両方が機能し、同じ出力を生成することに気付きました。Rubyがこれをどのように実現するのか(そして、自分の関数でどのように実現できるのか)疑問に思いました。

my_array = [["hello","goodbye"],["picture","perfect"]]

my_array.each do |array|

  puts array[0] + " " + array[1]

end

my_array.each do |first, second|

  puts first + " " + second

end

私の理解では、コードブロックを受け入れるメソッドの定義を作成する場合、yieldメソッドを使用して、コードブロックに引数を渡し、ブロックを呼び出します。しかし、提供されたコードブロックに応じて異なる引数を渡すように、yieldメソッドをどのように利用できますか?例の場合、yieldメソッドは、ブロック内で2つのパラメーター(つまり、1番目と2番目)が使用されると個々の配列要素を渡し、1つのパラメーターがブロック内で使用されると(つまり、配列)、配列自体を渡すように見えます。 )。

4

1 に答える 1

1

どちらもここで特別なことをしているeachわけyieldではありません。それがブロック引数の仕組みです。次の簡単な例を考えてみましょう。

def f(x) yield x end

そして今、何が起こるかを見ることができます:

>> f([1,2]) { |a| puts a.inspect }
[1, 2]
>> f([1,2]) { |a, b| puts "#{a} - #{b}" }
1 - 2
>> f([1,2]) { |a, b, c| puts "#{a} - #{b} - #{c}" }
1 - 2 - 

割り当てでも同様の破壊が見られます。

a, b = [1, 2]

スプラットで明示的に行うこともできます:

a, b = *[1, 2]

またはこのように:

def g(x) yield *x end
g([1, 2]) { |a, b| puts "#{a} - #{b}" }

おそらく、ブロックは与えられるものの種類を知っているので、ブロックは引数をアンパックするのに適しています。g関数は、その引数がスプラブル (つまり、配列) であることを認識している必要がありますが、そうではないことに注意してくださいf。の呼び出しにf「どういうことか」というロジックをうまくまとめて、ロジックの半分を自分自身の中に埋めています。違いが明らかになる 1 つの場所は、ハッシュで Enumerable メソッドを使用する場合です。xfg

{ :where => :is, :pancakes => :house? }.map { |k, v| ... }

Enumerable#mapハッシュがキーと値の 2 つの要素配列で機能することを知る必要はありません。単に物事を渡し、詳細については他の人に任せます。

于 2013-03-19T06:46:06.737 に答える