检查是否定义了一个变量?

如何检查一个变量是否在Ruby中定义?是否有# eyz0类型的方法可用?

349366 次浏览

defined?(your_var)将工作。根据你在做什么,你也可以这样做your_var.nil?

使用defined?关键字(文档)。它将返回一个String类型的项目,或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"

如果它存在,你什么也不做,如果它不存在,你就创建它,这是很有用的。

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

这只创建一次新实例。之后它就一直返回var。

这里有一些代码,没有火箭科学,但它工作得足够好

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

显然,着色代码是不必要的,在这个玩具示例中只是一个漂亮的可视化。

上述语句的正确语法是:

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)。该语法将返回一个true/false值,用于if语句的计算。

你可以试试:

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

因为它返回一个布尔值。

试着用“除非”而不是“如果”

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
< p >使用# EYZ0 < br > # EYZ0 < / >强. .;)

请注意“定义的”和“指定的”之间的区别。

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

X是定义的,即使它从未被赋值!

此外,你可以检查它是否通过插值在字符串中定义,如果你编码:

puts "Is array1 defined and what type is it? #{defined?(@array1)}"
如果定义了类型,系统会告诉你。 如果没有定义,它将返回一个警告,说变量没有初始化

希望这能有所帮助!:)

正如许多其他示例所示,在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

警告:常见的Ruby模式

这是关键的答案:defined?方法。以上接受答案完美地说明了这一点。

但是有一条鲨鱼,潜伏在海浪下面

看看下面这个常见的红宝石图案:

 def method1
@x ||= method2
end


def method2
nil
end
  1. method2总是返回nil
  2. 第一次调用method1时,没有设置@x变量——因此将运行method2。而且
  3. method2@x设置为nil

但是第二次调用method1会发生什么呢?

记住@x已经被设置为nil。但是method2仍然会再次运行!!如果method2是一个昂贵的事业,这可能不是你想要的东西。

defined?方法来拯救:

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

与大多数事情一样,关键在于实现细节。

应该提到的是,使用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')

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

留下一个非常简单的例子,以防有用。

当变量不存在:

if defined? a then "hi" end
# => nil

当变量确实存在:

a = 2
if defined? a then "hi" end
# => "hi"