Обеспечьте ценность для себя при использовании вызова ProС#

При использовании вызова ProС# для вызова лямбда-функции в Ruby self всегда заканчивается значением, которое оно имело при определении функции, а не значением, которое оно имеет при вызове функции, например:

$p = lambda { self }

class Dummy
  def test
    $p.call
  end
end

d = Dummy.new

> d.test
=> main

Вызов test возвращает main, когда то, что я намеревался вернуть, #<Dummy:0xf794> - экземпляр Dummy, который был значением self в точке кода, в котором я вызывал $p.

В Javascript я бы просто передал объект, который я хочу быть "вызываемым" в качестве первого аргумента call. Есть ли такая возможность в Ruby, позволяющая мне установить произвольный объект или, по крайней мере, текущее значение self, как новое значение для self при вызове Proc?

Ответы

Ответ 1

Вы ищете instance_eval, который оценивает лямбда в контексте вызывающего объекта.

>> $p = proc { self }
=> #<Proc:[email protected](irb):1 (lambda)>
>> class Dummy
>>   def test
>>     $p.call
>>   end
>> 
>>   def test1
>>     instance_eval(&$p)
>>   end
>> end

>> d = Dummy.new
=> #<Dummy:0x946f7c8>
>> d.test
=> main
>> d.test1
=> #<Dummy:0x946f7c8>

Ответ 2

Вы можете использовать instance_exec, потому что он позволяет передавать аргументы блоку, тогда как instance_eval не делает.

def eval_my_proc_with_args(*args, &block)
  instance_exec(*args, &block)
end

Ответ 3

lambda определяет замыкание, которое означает, что оно инкапсулирует среду, в которой она была определена, когда она была определена. Если вы хотите, чтобы я был вызывающим, просто определите обычный метод или еще лучше используйте блок.