wake-up-neo.net

Prüfen, ob eine Variable definiert ist?

Wie kann ich überprüfen, ob eine Variable in Ruby definiert ist? Gibt es eine isset- Methode?

560
Readonly

Verwenden Sie das Schlüsselwort defined? ( documentation ). Es wird eine Zeichenfolge mit der Art des Elements oder nil zurückgegeben, wenn es nicht vorhanden ist.

>> a = 1
 => 1
>> defined? a
 => "local-variable"
>> defined? b
 => nil
>> defined? nil
 => "nil"
>> defined? String
 => "constant"
>> defined? 1
 => "expression"

Skalee kommentierte: "Es ist zu beachten, dass die Variable, die auf Null gesetzt ist, initialisiert wird."

>> n = nil  
>> defined? n
 => "local-variable"
768
Ricardo Acras

Dies ist nützlich, wenn Sie nichts tun möchten, wenn es existiert, aber es erstellen, wenn es nicht existiert.

def get_var
  @var ||= SomeClass.new()
end

Dadurch wird die neue Instanz nur einmal erstellt. Danach kehrt der var immer wieder zurück.

90
danmayer

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 Sie (var) durch Ihre Variable. Diese Syntax gibt einen Wahr/Falsch-Wert zur Auswertung in der if-Anweisung zurück.

70
foomip

defined?(your_var) wird funktionieren. Je nachdem, was Sie tun, können Sie auch etwas wie your_var.nil? tun.

18
digitalsanctum

Versuchen Sie "außer" 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
15
user761856

Verwenden Sie defined? YourVariable
Halten Sie es einfach dumm ..;)

9
Saqib R.

Hier ist etwas 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

Natürlich ist der Farbcode nicht notwendig, nur eine schöne Visualisierung in diesem Spielzeugbeispiel.

7
Sardathrion

WARNUNG Re: Ein allgemeines Rubinmuster

Dies ist die Schlüsselantwort: die defined?-Methode. Die akzeptierte Antwort oben veranschaulicht dies perfekt. 

Aber unter den Wellen lauert ein Hai ...

Betrachten Sie diese Art von allgemeinem Ruby-Muster: 

 def method1
    @x ||= method2
 end

 def method2
    nil
 end

method2 gibt immer nil zurück. Wenn Sie method1 zum ersten Mal aufrufen, wird die Variable @x nicht festgelegt. Daher wird method2 ausgeführt. und method2 setzen @x auf nil. Das ist gut und alles gut und gut. Aber was passiert beim zweiten Aufruf von method1?

Denken Sie daran, dass @x bereits auf null gesetzt wurde. But method2 wird immer noch ausgeführt !! Wenn method2 ein kostspieliges Unterfangen ist, ist dies möglicherweise nicht das, was Sie wollen.

Lassen Sie die defined?-Methode zur Rettung kommen - bei dieser Lösung wird dieser bestimmte Fall behandelt - verwenden Sie Folgendes:

  def method1
    return @x if defined? @x
    @x = method2
  end

Der Teufel steckt im Detail: Sie können diesen lauernden Hai jedoch mit der defined?-Methode umgehen.

6
BKSpurgeon

Du kannst es versuchen:

unless defined?(var)
  #Ruby code goes here
end
=> true

Weil es einen Boolean zurückgibt.

5
Bruno Barros

Wie viele andere Beispiele zeigen, benötigen Sie für eine logische Auswahl in Ruby nicht wirklich einen booleschen Wert. Es wäre eine schlechte Form, alles zu einem Boolean zu zwingen, es sei denn, Sie benötigen tatsächlich einen Boolean. 

Aber wenn Sie unbedingt einen Boolean brauchen. Benutzen !! (Bang Bang) oder "Falsches Falsches enthüllt die Wahrheit".

› irb
>> a = nil
=> nil
>> defined?(a)
=> "local-variable"
>> defined?(b)
=> nil
>> !!defined?(a)
=> true
>> !!defined?(b)
=> false

Warum lohnt es sich normalerweise nicht 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, in dem es wichtig ist, weil es auf den impliziten Zwang des booleschen Werts in seine Zeichenfolgendarstellung angewiesen ist.

>> puts "var is defined? #{!!defined?(a)} vs #{defined?(a)}"
var is defined? true vs local-variable
=> nil
3
user325634

Es sollte erwähnt werden, dass die Verwendung von defined zur Überprüfung, ob ein bestimmtes Feld in einem Hash gesetzt 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, aber defined? var['unknown'] wird in der Zeichenfolge "method" ausgewertet, sodass der if-Block ausgeführt wird

edit: Die korrekte Notation zur Überprüfung, ob ein Schlüssel in einem Hash existiert, wäre:

if var.key?('unknown')
3
leberknecht

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 ist definiert, obwohl es niemals zugewiesen ist!

2
Robert Klemme

defined? ist großartig. Wenn Sie sich jedoch in einer Rails-Umgebung befinden, können Sie auch try verwenden, insbesondere wenn Sie den Namen einer dynamischen Variablen ü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
0
John Donner

Außerdem können Sie durch Interpolation überprüfen, ob es in einem String definiert ist, wenn Sie Folgendes codieren: 

puts "Is array1 defined and what type is it? #{defined?(@array1)}"

Das System teilt Ihnen den Typ mit, falls es definiert ist .. Wenn es nicht definiert ist, wird nur eine Warnung ausgegeben, dass die Variable nicht initialisiert ist.

Hoffe das hilft! :)

0
Elliott