Переплет блоков в Ruby - PullRequest
2 голосов
/ 18 июля 2010

Меня смущает определение связывания блоков в ruby.Вот два примера:

def redfine_a(&block)
  a = 2
  puts eval("a", block.binding)
  block.call
end
a = "hello"
puts redfine_a {a}

Этот может работать с ожидаемым результатом, а второй:

def redefine_a(&block)
  a= 2
  puts eval("a", block.binding)
  block.call
end

puts redefine_a{a= "hello"}

будет жаловаться:

undefined local variable or method `a' for main:Object (NameError)

ПослеЯ удалил puts eval("a", block.binding), мой код запускается:

def redefine_a(&block)
  a= 2
  block.call
end

puts redefine_a{a= "hello"}

Где я не прав?

Ответы [ 2 ]

9 голосов
/ 18 июля 2010

block.binding - это среда, в которой определен блок до его запуска.

3 голосов
/ 18 июля 2010

В вашем коде контекстом, в котором определен блок, является объект main, поэтому строка eval("a", block.binding) вернет значение a в main.В вашем первом примере a определен в main, и поэтому код выполняется, во втором примере нет a в основном и поэтому ошибка.

В обоих случаях, однако, a=2 в вашем redefine_a методе не может быть никакого эффекта.

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