/ / variável local indefinida ou método após eval quando não declarado antes - ruby, eval

variável local indefinida ou método após eval quando não declarado antes - ruby, eval

Em Ruby

2.1.2 :068 >   a=1
=> 1
2.1.2 :069 > eval("a=4")
=> 4
2.1.2 :070 > a
=> 4
2.1.2 :071 > eval("b=4")
=> 4
2.1.2 :072 > b
NameError: undefined local variable or method `b" for main:Object

Portanto, a questão é por que a variável "b" será "variável local indefinida ou método", mas a variável "a" é igual a 4?

Respostas:

1 para resposta № 1

Quando você liga para o eval lambda, você cria um novo escopo para o código que executa.

Seria como criar e executar um novo lambda. Se você declarar a antes e, em seguida, use uma variável chamada a em seu lambda, você deve usar o mesmo. Mas se você não declarar b antes do lambda, eval criará sua própria variável e a excluirá no final.


1 para resposta № 2
 puts "outside binding #{binding.__id__}"
a = 1
puts "outside a #{a.__id__}"
eval "b="b"; puts "inside binding #{binding.__id__}"; puts "inside a #{binding.local_variable_get(:a).__id__}"; a="c"; puts "inside after a #{a.__id__}""
puts "outside after a #{a.__id__}"

execute o código acima, você pode ver que o lado de foravinculação e a vinculação interna está usando IDs diferentes. mas compartilhe o mesmo a. quando rodamos eval, ruby ​​irá copiar a ligação externa, então ele usará o mesmo a; mas b é definido na ligação interna, quando a avaliação é concluída, a ligação interna é perdida e b. Na verdade, o escopo do bloco é igual a este.