Укажите значение для себя при использовании вызова Proc # - PullRequest
22 голосов
/ 13 ноября 2009

При использовании вызова Proc # для вызова лямбда-функции в 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?

Ответы [ 3 ]

23 голосов
/ 13 ноября 2009

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

>> $p = proc { self }
=> #<Proc:0x95cece4@(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>
22 голосов
/ 11 февраля 2011

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

def eval_my_proc_with_args(*args, &block)
  instance_exec(*args, &block)
end
1 голос
/ 13 ноября 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...