回答:
defined?
キーワード(documentation)を使用します。アイテムの種類、またはnil
存在しない場合はStringを返します。
>> 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"
||=
演算子を含む)を参照してください。
defined?
変数を定義しても、そのブロック内で定義されている変数に対してtrueが返されます。
defined?
そのようなメソッドはブール値を返しますか?
!!defined?(object_name)
これは、存在する場合は何もせず、存在しない場合は作成する場合に便利です。
def get_var
@var ||= SomeClass.new()
end
これにより、新しいインスタンスが1回だけ作成されます。その後、varを返し続けます。
||=
混乱の痛みを感じないように、ブール値では使用しないでください。
nil
を実際に評価したくない場合を除いて、このイディオムを返す可能性があるものは避けてくださいnil
var = (var or var.nil?)
上記のステートメントの正しい構文は次のとおりです。
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値を返します。
defined?(var) == nil
?
.nil?
彼らが言うように、呼び出しを使用することはより慣用的です。nil
比較演算子を使用するよりもオブジェクトに問い合わせる方が「オブジェクト指向」です。どちらも読みにくいので、より多くの製品を出荷するのに役立つ方を使用してください。
「if」ではなく「unless」を試す
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
ここにいくつかのコードがありますが、ロケット科学はありませんが、それは十分に機能します
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
明らかに、色付けコードは必要ありません。このおもちゃの例では見栄えが良いだけです。
nil?
オプションであるためです。
これが鍵となる答えです:defined?
メソッド。上記の受け入れられた答えはこれを完全に示しています。
しかし、波の下に潜んでいるサメがいます...
この種の一般的なルビパターンを考えてみましょう:
def method1
@x ||= method2
end
def method2
nil
end
method2
常に戻りますnil
。を初めて呼び出すmethod1
とき、@x
変数は設定されていないためmethod2
、実行されます。そして、method2
設定されます@x
しnil
。それは結構です、そしてすべてうまくいきます。しかし、2回目に電話するとmethod1
どうなりますか?
@xはすでにnilに設定されていることに注意してください。But method2
再び実行されます!! method2がコストのかかる作業である場合、これはあなたが望むものではないかもしれません。
してみましょうdefined?
この溶液を用いて、特定のケースが処理されていること- -メソッドが救助に来て、次を使用します。
def method1
return @x if defined? @x
@x = method2
end
悪魔は詳細にありますが、そのdefined?
方法で潜んでいるサメを回避できます。
他の多くの例が示すように、ルビで論理的な選択を行うためにメソッドからブール値を実際に必要としない。実際にブール値が必要でない限り、すべてをブール値に強制するのは不適切な形式です。
ただし、ブール値が絶対に必要な場合。使用する !!(バンバン)または「偽りの偽りは真実を明らかにする」
› 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
defined
特定のフィールドがハッシュに設定されているかどうかを確認するためにを使用すると、予期しない動作をする可能性があることに注意してください。
var = {}
if defined? var['unknown']
puts 'this is unexpected'
end
# will output "this is unexpected"
構文はここでは正しいですがdefined? var['unknown']
、文字列として評価される"method"
ため、if
ブロックが実行されます
編集:キーがハッシュに存在するかどうかをチェックするための正しい表記は次のようになります:
if var.key?('unknown')
「定義済み」と「割り当て済み」の違いに注意してください。
$ ruby -e 'def f; if 1>2; x=99; end;p x, defined? x; end;f'
nil
"local-variable"
xは割り当てられていなくても定義されています!
NameError Exception: undefined local variable or method
が、変数の割り当て/メンションがヒットしなかったifブロックにあると混乱しました。
nil
が初期化されていることは注目に値します。