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"
Das Beispielprogramm bestimmt wird im Rahmen eines Foo
Instanz beliebigen Code auszuwerten. Es tut das, aber die Bindung ist mit den lokalen Variablen aus der code
Methode "verschmutzt". Ich möchte nicht, dass foo
, n
oder code
für den Evaluierungscode sichtbar sind. Die gewünschte Ausgabe ist:Erstellen blank Bindung oben im Rahmen eines Objekts
#=> 42
#=> nil
Wie kann ich eine Bindung ist, dass (a) im Rahmen der Objektinstanz, aber (b) frei von irgendwelchen lokalen Variablen?
Der Grund, dass ich eine Bindung statt nur instance_eval(code)
mit erschaffe, dass in den real usage ich keep the binding around for later usage, muß die lokalen Variablen in ihr geschaffen zu bewahren.
Sie haben einige der lokalen Variablen entfernt, aber nicht alle: 'Definiert? (N)' ist '" local-variable "' weil Sie 'binding' genannt haben. Es ist sauberer, aber es ist nicht leer. – Phrogz
ist die aktualisierte Version leer genug? – phoet
Ja, die aktualisierte Version funktioniert. Vielen Dank! Beachten Sie jedoch, dass bei jedem Aufruf von "b" eine neue leere Bindung erstellt wird. Wenn dies das ist, was Sie wollen, ist die Antwort perfekt. Wenn Sie stattdessen - wie ich - die gleiche Bindung beibehalten möchten, um die lokalen Variablen von jedem Lauf zu akkumulieren, müssten Sie etwas wie "def b; @b || = Bindung; Ende.Ich gebe Ihnen die Akzeptanz, weil die Verwendung der Instanz als Speicher eleganter ist als die Verwendung eines separaten Objekts (wie in meiner Antwort); Auf andere Weise erzwingt dies eine neue Instanzvariable auf Ihrem Objekt, die Sie möglicherweise nicht haben möchten. – Phrogz