Руби лямбда процы и 'instance_eval' - PullRequest
0 голосов
/ 03 октября 2018

Когда я передаю лямбду в instance_eval как блок, кажется, что передается дополнительный аргумент:

lamb = -> { puts 'hi' }
proc = Proc.new { puts 'hi' }
instance_eval(&lamb)
# >> ArgumentError: wrong number of arguments (given 1, expected 0)
#    from (irb):5:in `block in irb_binding'
#    from (irb):7:in `instance_eval'
instance_eval(&proc)
# => hi
instance_exec(&lamb)
# => hi

Почему это так?Обратите внимание, что этот вопрос НЕ о том, почему лямбда выдает ошибку.Это хорошо понято.Вопрос в том, ПОЧЕМУ instance_eval отправляет self получателя в качестве параметра.Это не нужно, и сбивает с толку.И AFAIK не задокументировано.

Это помогает, но не объясняет, ПОЧЕМУ ruby ​​будет делать это таким образом.Весь смысл instance_eval в том, чтобы установить self для получателя;зачем путать вещи, также передавая self в proc?

1 Ответ

0 голосов
/ 03 октября 2018

Из документов

Для процедур, созданных с использованием лямбды или -> (), генерируется ошибка, если неверное количество параметров передается в Proc с несколькими параметрами.Для проков, созданных с использованием Proc.new или Kernel.proc, дополнительные параметры отбрасываются без уведомления.

В вашем случае lamb и proc вызываются с одним параметром

Из документов instance_eval

Когда instance_eval передается блоку, obj также передается в качестве единственного аргумента блока

instance_eval является методомBasicObject класс и может быть вызван внутри экземпляра.Таким образом, данный блок будет иметь доступ к закрытым методам, например.

class Test
  def call
    secret_number + 100
  end
  private
  def secret_number
    42
  end
end

test = Test.new
show_secret = -> (obj) { puts secret_number }

test.instance_eval(&show_secret) # print 42

Без экземпляра self текущего контекста будет передано в качестве аргумента.Я думаю, что instance_eval был разработан больше для вызова его в объектах.

Из документов instance_eval

Чтобы установить контекст, переменная selfустанавливается во время выполнения кода как obj, предоставляя коду доступ к переменным экземпляра obj и закрытым методам.

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