首页 文章

检查是否定义了变量?

提问于
浏览
551

如何检查Ruby中是否定义了变量?是否有 isset 类型的方法?

14 回答

  • 15

    使用 defined? 关键字(documentation) . 它将返回一个带有项目类型的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"
    
  • 2

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

    上述语句的正确语法是:

    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值以进行评估 .

  • 3

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

    But there is a shark, lurking beneath the waves...

    考虑这种类型的常见ruby模式:

    def method1
        @x ||= method2
     end
    
     def method2
        nil
     end
    

    method2 始终返回 nil . 第一次调用 method1 时, @x 变量未设置 - 因此将运行 method2 . 和 method2@x 设置为 nil . 那很好,一切都很好 . 但是第二次调用 method1 会发生什么?

    记住@x已经设置为nil . But method2 还会再次运行吗?如果method2是一项代价高昂的工作,那么这可能不是您想要的 .

    defined? 方法得到解决 - 使用这个解决方案来处理特定情况 .

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

    魔鬼在细节中:但你可以通过“更大的船”来逃避潜伏的鲨鱼 .

  • 18

    你可以试试:

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

    因为它返回一个布尔值 .

  • 5

    defined?(your_var) 会奏效 . 根据你正在做的事情你也可以做 your_var.nil?

  • 759

    正如许多其他示例所示,您实际上不需要方法中的布尔值来在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
    
  • 0

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

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

    系统将告诉您类型是否已定义 . 如果没有定义,它只会返回一个警告,说明变量未初始化 .

    希望这可以帮助! :)

  • 0

    这里有一些代码,没有什么火箭科学,但它运作良好

    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
    

    显然,着色代码不是必需的,只是这个玩具示例中的一个很好的视觉效果 .

  • 5

    如果您确实存在则不执行任何操作,但如果它不存在则创建它,这将非常有用 .

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

    这只会创建一次新实例 . 之后它只是继续返回var .

  • 3

    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
    
  • 5

    请注意“已定义”和“已分配”之间的区别 .

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

    即使从未分配过x,也会定义x!

  • 9

    使用 defined? YourVariable
    Keep it simple silly ..;)

  • 90

    尝试“除非”而不是“如果”

    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
    

相关问题