web-dev-qa-db-ja.com

変数が定義されているかどうかを確認しますか?

Rubyで変数が定義されているかどうかをどうやって確認できますか?利用可能なisset- typeメソッドはありますか?

563
Readonly

defined?キーワードを使用してください( documentation )。アイテムの種類を含む文字列を返します。存在しない場合はnilを返します。

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

Skaleeがコメントしたように、「nilに設定された変数は初期化されていることに注目する価値があります。」

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

存在する場合は何もしないで、存在しない場合は作成したい場合に便利です。

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

これは新しいインスタンスを一度だけ作成します。その後はvarを返し続けます。

91
danmayer

上記のステートメントの正しい構文は次のとおりです。

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

変数を(var)に置き換えます。この構文は、if文の評価用にtrue/false値を返します。

70
foomip

defined?(your_var)は動作します。自分のしていることによっては、your_var.nil?のようなこともできます。

18
digitalsanctum

「if」の代わりに「except」を試してください。

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

defined? YourVariableを使う
愚かなことに単純にしてください ..;)

9
Saqib R.

ここにいくつかのコードがあります、ロケット科学は何もありません、しかしそれは十分にうまくいきます

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

明らかに、カラーコードは必要ではありません。このおもちゃの例ではNice visualationです。

7
Sardathrion

警告Re:一般的なRubyパターン

これが重要な答えです。defined?メソッドです。上記の受け入れられた答えはこれを完全に説明します。

しかし、波の下に潜んでいるサメがいる...

この種の一般的なRubyパターンを考えます。

 def method1
    @x ||= method2
 end

 def method2
    nil
 end

method2は常にnilを返します。初めてmethod1を呼び出したときには、@x変数は設定されていません。したがって、method2が実行されます。そしてmethod2@xnilに設定します。それは結構です、そしてすべてが順調です。しかし、method1を2回呼び出したときはどうなりますか?

@xはすでにnilに設定されていることを忘れないでください。 But method2はまだ再実行されます。方法2がコストのかかる作業である場合、これはあなたが望むものではないかもしれません。

defined?メソッドが助けになるようにしましょう - この解決法では、その特定のケースが扱われます - 以下を使用してください:

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

悪魔は細部にあります:しかし、あなたはdefined?メソッドでその潜んでいるサメを回避することができます。

6
BKSpurgeon

あなたが試すことができます:

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

ブール値を返すからです。

5
Bruno Barros

他の多くの例が示すように、Rubyで論理的な選択をするためにメソッドからのブール値は実際には必要ありません。実際にブール値が必要でない限り、すべてをブール値に強制するのは適切ではありません。

あなたが絶対にブール値を必要とするならば。つかいます !! (bang bang)または "falsy falsyは真実を明らかにする"。

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

なぜそれが通常強制的にお金を払わないのか:

>> (!!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

これは、ブール値からその文字列表現への暗黙の型強制に依存しているために重要な例です。

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

ハッシュ内で特定のフィールドが設定されているかどうかを確認するためにdefinedを使用すると、予期しない動作をする可能性があることに注意してください。

var = {}
if defined? var['unknown']
  puts 'this is unexpected'
end
# will output "this is unexpected"

ここでの構文は正しいですが、defined? var['unknown']は文字列"method"に評価されるため、ifブロックが実行されます。

edit:キーがハッシュに存在するかどうかをチェックするための正しい表記法は次のようになります。

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

「定義済み」と「割り当て済み」の違いに注意してください。

$ Ruby -e 'def f; if 1>2; x=99; end;p x, defined? x; end;f'
nil
"local-variable"

割り当てられていないのにxが定義されています。

2
Robert Klemme

defined?は素晴らしいですが、もしあなたがRails環境にいるのであれば、特に動的変数名をチェックしたい場合にはtryを使うこともできます。

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

また、次のようにコーディングすると、内挿を通じて文字列内で定義されているかどうかを確認できます。

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

型が定義されていれば、システムからその型がわかります。定義されていない場合は、変数が初期化されていないという警告を返すだけです。

お役に立てれば! :)

0
Elliott