V 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
Takže otázkou je, prečo premenná "b" bude "nedefinovaná lokálna premenná alebo metóda", ale premenná "a" sa rovná 4?
odpovede:
1 pre odpoveď č. 1Keď zavoláte eval
lambda vytvoríte nový priestor pre spustený kód.
Bolo by vhodné vytvoriť a vykonať novú lambdu. Ak vyhlasujete a
pred a potom použite premennú nazvanú a
vo vašej lambde, budete používať to isté. Ale ak nehlásime b
pred lambdou, eval
vytvorí vlastnú premennú a na konci ju vymaže.
1 pre odpoveď č. 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__}"
spustite kód vyššie, môžete vidieť, že vonkuviazanie a vnútorné viazanie používa rôzne identifikátory. ale zdieľajú to isté. keď spustíme eval, rubín kopíruje vonkajšiu väzbu, takže použije rovnaký a; ale b je definované vo vnútri väzby, keď eval je vykonaná, vnútri väzba je stratená a tak je b. V skutočnosti je rozsah blokovania rovnaký ako tento.