0

以下が機能する理由を理解するのを手伝ってください。

class Dog
  def bark
    "woof"
  end
end

bark_string = Dog.new.bark
puts bark_string                   # "woof" - a string at this point
ref_to_bark = -> { bark_string }   # the string a moment ago is now the method again
ref_to_bark.call                   # "woof"

メソッドへの参照を proc/lambda でラップすると、元のメソッドへの参照が返されるのはなぜですか? それは私を困惑させます。

4

3 に答える 3

4

そうではありません。ref_to_barkを返すだけbark_stringで、barkメソッドは呼び出されません。

于 2012-06-01T15:15:56.163 に答える
3

Ruby のラムダ (およびブロックとプロシージャ) はクロージャーです。これは、ラムダが定義されているのと同じスコープで使用可能なローカル変数が、ラムダでアクセスできることを意味します。例えば:

foo = 42
l = lambda{ p foo }
l.call()
#=> 42

上記は、このコードが機能するという事実よりも驚くべきことではありません。

x = 17
[1,2,3].map do |n|
  n+x # Whoa, you can use _x_ here?!
end
#=> [18,19,20]

次のようなことをすると、もう少し驚くべきことになります。

def make_adder( x )
  ->(y){ x+y }
end
add10 = make_adder(10)
z = add10.call(32)     #=> 42

ここでも、ローカル変数x (メソッドに渡されるパラメーター) はラムダによって「閉じられ」、ラムダが呼び出されるたびにその値が参照用に保持されます。

したがって、あなたの例では、ラムダは単に変数を「キャプチャ」し、bark_string後でその値を返しています。メソッドが再度呼び出されることはありません。


クロージャーは、変数によって参照されるオブジェクトだけでなく、変数自体をキャプチャすることに注意してください。

x = "hello"
y = x         # reference the same _object_
l = ->{ x }   # close over the _variable_ itself
x = "world"   # change the variable to point to a new object

p y,          #=> "hello"     (same object as the original)
  l[]         #=> "world"     (new object)
于 2012-06-01T15:24:30.760 に答える
0

-> を使用して定義されたラムダは、ラムダ リテラルと呼ばれます。安定したラムダと呼ばれることもあります。以下も同じ結果を返します。

ref_to_bark = lambda { bark_string }

または

ref_to_bark = lambda { "woof" }
于 2012-06-01T15:19:32.810 に答える