检查是不是定义了变量?
Posted
技术标签:
【中文标题】检查是不是定义了变量?【英文标题】:Checking if a variable is defined?检查是否定义了变量? 【发布时间】:2010-09-22 06:27:34 【问题描述】:如何检查变量是否在 Ruby 中定义?是否有可用的isset
-type 方法?
【问题讨论】:
【参考方案1】:defined?(your_var)
可以。根据你在做什么,你也可以做类似your_var.nil?
【讨论】:
+1 表示your_var.nil?
,因为它返回 true 或 false,并且比 defined? var
更易于读写。谢谢你。
your_var.nil?
将导致错误:undefined local variable or method your_var
之前未定义...【参考方案2】:
使用 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"
【讨论】:
值得注意的是,设置为nil
的变量已初始化。
如果你想设置一个变量,如果它不存在,如果它不存在,请不要理会它,请参阅下面的@danmayer 的答案(涉及||=
运算符)。
这是我能想到的另一个奇怪之处。如果您在 if 块中定义了一个条件从未满足的变量,defined?
仍然为该块中定义的变量返回 true!跨度>
有没有像defined?
这样返回布尔值的方法?
返回真/假,!!defined?(object_name)
【参考方案3】:
如果你想在它存在时什么都不做,但如果它不存在就创建它,这很有用。
def get_var
@var ||= SomeClass.new()
end
这只会创建一次新实例。之后它只是不断返回 var。
【讨论】:
顺便说一句,这也是非常惯用的 Ruby,非常典型。 只是不要将||=
与布尔值一起使用,以免您感到困惑的痛苦。
和@AndrewMarshall 所说的一样,避免使用任何可能返回nil
的惯用语,除非您真的想要在每次调用它时评估表达式返回nil
如果您正在使用布尔值,并且如果变量未明确设置为 false,并且希望默认值为 true,则可以使用以下构造:var = (var or var.nil?)
@ArnaudMeuret Sort of, not really. -- 虽然它可能看起来不一样,但值得阅读该问题的答案。【参考方案4】:
这是一些代码,没有什么火箭科学,但它运行良好
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?
是可选的。【参考方案5】:
上述语句的正确语法是:
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 语句中进行评估。
【讨论】:
这不是必需的,因为在测试中使用 nil 时评估为 false 为什么不defined?(var) == nil
?
@vol7ron - 这是完全有效的语法。正如他们所说,使用对.nil?
的调用更为惯用。询问对象是否nil
比使用比较运算符更“面向对象”。两者都不难阅读,所以使用任何一个可以帮助您发布更多产品。
你指的是哪个声明?!?不要将答案用作对其他内容的评论。【参考方案6】:
你可以试试:
unless defined?(var)
#ruby code goes here
end
=> true
因为它返回一个布尔值。
【讨论】:
SyntaxError: compile error (irb):2: syntax error, unexpected $end, expecting kEND
使用unless
语句似乎过于复杂【参考方案7】:
尝试“除非”而不是“如果”
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
【讨论】:
这个答案增加了什么其他答案没有说的? 它以一种更有用的方式很好地回答了这个问题,不是吗? 红宝石风格指南说“赞成,除非在负面条件下结束”github.com/bbatsov/ruby-style-guide【参考方案8】:使用defined? YourVariable
保持简单傻 .. ;)
【讨论】:
【参考方案9】:请注意“定义”和“分配”之间的区别。
$ 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 块中时,我感到很困惑。【参考方案10】:
此外,您可以通过插值检查它是否在字符串中定义,如果您编写代码:
puts "Is array1 defined and what type is it? #defined?(@array1)"
如果定义了类型,系统会告诉你类型。 如果没有定义它只会返回一个警告说变量没有初始化。
希望这会有所帮助! :)
【讨论】:
【参考方案11】:正如许多其他示例所示,您实际上并不需要方法中的布尔值来在 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
【讨论】:
【参考方案12】:警告回复:常见的 Ruby 模式
这是关键答案:defined?
方法。上面接受的答案完美地说明了这一点。
但是有一条鲨鱼,潜伏在海浪之下……
考虑这种常见的红宝石模式:
def method1
@x ||= method2
end
def method2
nil
end
method2
总是返回 nil
。第一次调用 method1
时,@x
变量未设置 - 因此将运行 method2
。
而method2
将设置@x
为nil
。那很好,一切都很好。但是第二次拨打method1
会发生什么?
记住@x 已经被设置为nil。 But method2
仍将再次运行!!如果方法 2 是一项昂贵的工作,这可能不是您想要的。
让defined?
方法来救援 - 使用此解决方案,处理特定情况 - 使用以下内容:
def method1
return @x if defined? @x
@x = method2
end
魔鬼在细节中:但您可以使用defined?
方法避开潜伏的鲨鱼。
【讨论】:
你是完全正确的,感谢您强调这一特定警告【参考方案13】:应该提到的是,使用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')
【讨论】:
【参考方案14】: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
【讨论】:
【参考方案15】:留下一个非常简单的例子,以防万一。
当变量不存在时:
if defined? a then "hi" end
# => nil
当变量确实存在时:
a = 2
if defined? a then "hi" end
# => "hi"
【讨论】:
以上是关于检查是不是定义了变量?的主要内容,如果未能解决你的问题,请参考以下文章