Undefine Variable in Ruby
-
18-09-2019 - |
Frage
Lassen Sie uns sagen, ich bin mit irb
, und geben a = 5
. Wie kann ich die Definition von a
entfernen, so dass die Eingabe a
eine NameError
zurück?
Einige Kontext: later Ich möchte, dies zu tun:
context = Proc.new{}.binding
context.eval 'a = 5'
context.eval 'undef a' # though this doesn't work.
Lösung
Es gibt remove_class_variable , remove_instance_variable und remove_const Methoden, aber es gibt derzeit keine Entsprechung für lokale Variablen.
Andere Tipps
Sie können durch die Reduzierung des Umfangs un-Deklarieren der Variablen vermeiden, in der die Variable vorhanden ist:
def scope
yield
end
scope do
b = 1234
end
b # undefined local variable or method `b' for main:Object
Sie können immer ‚klar‘ irb der Registrierung von lokalen Variablen durch eine irb Subshell aufgerufen wird. Überlegen Sie, wie Bash-Shells arbeiten in Bezug auf unexported Umgebungsvariablen. Da Sie den interaktiven Modus metioned, sollte diese Lösung dafür arbeiten.
Was die Produktionscode, würde ich nicht auf lokale Variablen als Teil einer Lösung undefine wollen -. Für diese Art von Szenario verkeilt Hashes wahrscheinlich besser wäre
Hier ist, was ich meine:
$ irb
irb(main):001:0> a = "a"
=> "a"
irb(main):002:0> defined? a
=> "local-variable"
irb(main):003:0> irb # step into subshell with its own locals
irb#1(main):001:0> defined? a
=> nil
irb#1(main):002:0> a
NameError: undefined local variable or method `a' for main:Object
from /Users/dean/.irbrc:108:in `method_missing'
from (irb#1):2
irb#1(main):003:0> exit
=> #<IRB::Irb: @context=#<IRB::Context:0x1011b48b8>, @signal_status=:IN_EVAL, @scanner=#<RubyLex:0x1011b3df0>>
irb(main):004:0> a # now we're back and a exists again
=> "a"
Zur Zeit haben Sie keine mittlere globale Variablen, lokale Variablen und Klassenvariablen zu entfernen. Sie können Konstanten „remove_const“ Methode obwohl
entfernenIm Geist der Frage, könnten Sie die Variable auf einen Umfang begrenzen, vorausgesetzt, Sie sind in Ordnung mit anderen lokalen Variablen auf den gleichen Umfang erfasst werden kann. Dies ist nützlich, vor allem, wenn Sie etwas in einer Klasse definieren und nicht die lokalen Variable wollen in der Klassendeklaration bleiben um.
Die einzigen Möglichkeiten, wie ich denken kann, dies zu tun mit Integer#times
oder Array#each
wie so ist:
1.times do |a|
a = 5
# code…
end
[5].each do |a|
# code…
end
Es gibt wahrscheinlich auch andere, noch sauberere Wege zu einem Block neben diesen zu begrenzen. Diese sind nicht so sauber, wie Ich mag würde, und ich würde gerne sehen, wenn jemand eine sauberere Methode hat zu verwenden, dies zu tun.