class Foo
def self.run(n,code)
foo = self.new(n)
@env = foo.instance_eval{ binding }
@env.eval(code)
end
def initialize(n)
@n = n
end
end
Foo.run(42, "p @n, defined? foo")
#=> 42
#=> "local-variable"
Il programma di esempio riportato sopra intende valutare codice arbitrario nell'ambito di un'istanza Foo
. Lo fa, ma il binding è "inquinato" con le variabili locali dal metodo code
. Non voglio che foo
, n
o code
siano visibili al codice eval'd. L'uscita desiderata è:Crea associazione vuota nell'ambito di un oggetto
#=> 42
#=> nil
Come si crea un legame che è (a) nell'ambito dell'istanza dell'oggetto, ma (b) privo di variabili locali?
La ragione per cui sto creando un legame invece di utilizzare instance_eval(code)
è che nel real usage ho bisogno di keep the binding around for later usage, per preservare le variabili locali creati in esso.
Hai rimosso alcune delle variabili locali, ma non tutte: 'defined? (N)' è '" local-variable "' a causa di dove hai chiamato 'binding'. È più pulito, ma non è vuoto. – Phrogz
la versione aggiornata è abbastanza bianca? – phoet
Sì, la versione aggiornata funziona. Grazie! Notare, tuttavia, che crea un nuovo bind vuoto ogni volta che viene chiamato 'b'. Se questo è quello che vuoi, la risposta è perfetta. Se invece, come me, vuoi mantenere lo stesso legame per accumulare le variabili locali da ogni corsa, dovresti fare qualcosa come "def b; @b || = vincolante; FINE'.Ti darò l'accettazione perché in qualche modo utilizzo l'istanza in quanto l'archiviazione è più elegante di un oggetto separato (come nella mia risposta); in altri modi questo forza una nuova variabile di istanza sul tuo oggetto che potresti non desiderare di avere. – Phrogz