Wie kann ich überprüfen, ob in Ruby eine Variable definiert ist? Gibt es eine isset
Methode vom Typ?
Wie kann ich überprüfen, ob in Ruby eine Variable definiert ist? Gibt es eine isset
Methode vom Typ?
Antworten:
Verwenden Sie das defined?
Schlüsselwort ( Dokumentation ). Es wird eine Zeichenfolge mit der Art des Elements zurückgegeben, oder nil
wenn es nicht vorhanden ist.
>> a = 1
=> 1
>> defined? a
=> "local-variable"
>> defined? b
=> nil
>> defined? nil
=> "nil"
>> defined? String
=> "constant"
>> defined? 1
=> "expression"
Wie Skalee kommentierte: "Es ist erwähnenswert, dass die Variable, die auf Null gesetzt ist, initialisiert wird."
>> n = nil
>> defined? n
=> "local-variable"
||=
Operators) weiter unten.
defined?
für eine in diesem Block definierte Variable immer noch true zurückgegeben!
defined?
solche Methode , die einen Booleschen Wert zurückgibt?
!!defined?(object_name)
Dies ist nützlich, wenn Sie nichts tun möchten, wenn es vorhanden ist, sondern es erstellen möchten, wenn es nicht vorhanden ist.
def get_var
@var ||= SomeClass.new()
end
Dadurch wird die neue Instanz nur einmal erstellt. Danach wird die Var einfach weiter zurückgegeben.
||=
Sie es nur nicht mit booleschen Werten, damit Sie nicht den Schmerz der Verwirrung spüren.
nil
sei denn, Sie möchten den Ausdruck wirklich jedes Mal bewerten, wenn er aufgerufen wird, wenn er zurückkehrtnil
var = (var or var.nil?)
Die korrekte Syntax für die obige Anweisung lautet:
if (defined?(var)).nil? # will now return true or false
print "var is not defined\n".color(:red)
else
print "var is defined\n".color(:green)
end
Ersetzen ( var
) durch Ihre Variable. Diese Syntax gibt einen True / False-Wert zur Auswertung in der if-Anweisung zurück.
defined?(var) == nil
?
.nil?
ist idiomatischer, wie sie sagen. Es ist "objektorientierter", ein Objekt zu fragen, ob es nil
einen Vergleichsoperator verwendet. Beides ist nicht schwer zu lesen. Verwenden Sie also dasjenige, mit dem Sie mehr Produkte versenden können.
defined?(your_var)
wird funktionieren. Je nachdem, was Sie tun, können Sie auch so etwas tunyour_var.nil?
your_var.nil?
weil es true oder false zurückgibt und viel besser zu lesen und zu schreiben ist als defined? var
. Danke dafür.
your_var.nil?
wird zu einem Fehler führen: undefined local variable or method your_var
wenn nicht vorher definiert ...
Versuchen Sie "es sei denn" anstelle von "wenn"
a = "apple"
# Note that b is not declared
c = nil
unless defined? a
puts "a is not defined"
end
unless defined? b
puts "b is not defined"
end
unless defined? c
puts "c is not defined"
end
Hier ist ein Code, nichts Raketenwissenschaft, aber es funktioniert gut genug
require 'rubygems'
require 'rainbow'
if defined?(var).nil? # .nil? is optional but might make for clearer intent.
print "var is not defined\n".color(:red)
else
print "car is defined\n".color(:green)
end
Der Farbcode ist natürlich nicht erforderlich, nur eine schöne Darstellung in diesem Spielzeugbeispiel.
nil?
optional ist.
Dies ist die Schlüsselantwort: die defined?
Methode. Die oben akzeptierte Antwort veranschaulicht dies perfekt.
Aber da lauert ein Hai unter den Wellen ...
Betrachten Sie diese Art von häufigem Rubinmuster:
def method1
@x ||= method2
end
def method2
nil
end
method2
kehrt immer zurück nil
. Beim ersten Aufruf method1
wird die @x
Variable nicht gesetzt - daher method2
wird sie ausgeführt. und method2
wird eingestellt @x
auf nil
. Das ist in Ordnung und alles schön und gut. Aber was passiert beim zweiten Anruf method1
?
Denken Sie daran, dass @x bereits auf Null gesetzt wurde. But method2
wird noch wieder laufen !! Wenn Methode2 ein kostspieliges Unterfangen ist, ist dies möglicherweise nicht das, was Sie wollen.
Lassen Sie die defined?
Methode zur Rettung kommen - mit dieser Lösung wird dieser spezielle Fall behandelt - verwenden Sie Folgendes:
def method1
return @x if defined? @x
@x = method2
end
Der Teufel steckt im Detail: Aber mit der defined?
Methode können Sie diesem lauernden Hai ausweichen .
Du kannst es versuchen:
unless defined?(var)
#ruby code goes here
end
=> true
Weil es einen Booleschen Wert zurückgibt.
SyntaxError: compile error (irb):2: syntax error, unexpected $end, expecting kEND
unless
Aussage zu verwenden scheint zu kompliziert
Wie viele andere Beispiele zeigen, benötigen Sie keinen Booleschen Wert aus einer Methode, um logische Entscheidungen in Ruby zu treffen. Es wäre eine schlechte Form, alles zu einem Booleschen Wert zu zwingen, es sei denn, Sie benötigen tatsächlich einen Booleschen Wert.
Aber wenn Sie unbedingt einen Booleschen Wert brauchen. Verwenden !! (Bang Bang) oder "Falsy Falsy enthüllt die Wahrheit".
› irb
>> a = nil
=> nil
>> defined?(a)
=> "local-variable"
>> defined?(b)
=> nil
>> !!defined?(a)
=> true
>> !!defined?(b)
=> false
Warum es sich normalerweise nicht lohnt, zu zwingen:
>> (!!defined?(a) ? "var is defined".colorize(:green) : "var is not defined".colorize(:red)) == (defined?(a) ? "var is defined".colorize(:green) : "var is not defined".colorize(:red))
=> true
Hier ist ein Beispiel, wo es wichtig ist, weil es auf dem impliziten Zwang des booleschen Werts zu seiner Zeichenfolgendarstellung beruht.
>> puts "var is defined? #{!!defined?(a)} vs #{defined?(a)}"
var is defined? true vs local-variable
=> nil
Es sollte erwähnt werden, dass sich die Verwendung defined
zur Überprüfung, ob ein bestimmtes Feld in einem Hash festgelegt ist, möglicherweise unerwartet verhält:
var = {}
if defined? var['unknown']
puts 'this is unexpected'
end
# will output "this is unexpected"
Die Syntax ist hier korrekt, wird jedoch defined? var['unknown']
als Zeichenfolge ausgewertet "method"
, sodass der if
Block ausgeführt wird
Bearbeiten: Die korrekte Notation zum Überprüfen, ob ein Schlüssel in einem Hash vorhanden ist, lautet:
if var.key?('unknown')
Bitte beachten Sie die Unterscheidung zwischen "definiert" und "zugewiesen".
$ ruby -e 'def f; if 1>2; x=99; end;p x, defined? x; end;f'
nil
"local-variable"
x wird definiert, obwohl es nie zugewiesen wird!
NameError Exception: undefined local variable or method
und war verwirrt, als die einzige Zuweisung / Erwähnung der Variablen in einem if-Block war, der nicht getroffen wurde.
Sie können auch überprüfen, ob es in einer Zeichenfolge durch Interpolation definiert ist, wenn Sie Folgendes codieren:
puts "Is array1 defined and what type is it? #{defined?(@array1)}"
Das System teilt Ihnen den Typ mit, wenn er definiert ist. Wenn es nicht definiert ist, wird nur eine Warnung zurückgegeben, die besagt, dass die Variable nicht initialisiert ist.
Hoffe das hilft! :) :)
defined?
ist großartig, aber wenn Sie sich in einer Rails-Umgebung befinden, können Sie diese auch verwenden try
, insbesondere in Fällen, in denen Sie einen dynamischen Variablennamen überprüfen möchten:
foo = 1
my_foo = "foo"
my_bar = "bar"
try(:foo) # => 1
try(:bar) # => nil
try(my_foo) # => 1
try(my_bar) # => nil
nil
ist, initialisiert wird.