Ruby测试变量的定义

时间:2011-10-31 18:57:11

标签: ruby

我知道还有其他类似问题,例如:

  1. Ruby: how to check if variable exists within a hash definition
  2. Checking if a variable is defined?
  3. 但答案并不完全令人满意。

    我有:

    ruby-1.9.2-p290 :001 > a=Hash.new
     => {} 
    ruby-1.9.2-p290 :002 > a['one']="hello"
     => "hello"
    ruby-1.9.2-p290 :006 > defined?(a['one']['some']).nil?
     => false 
    ruby-1.9.2-p290 :007 > a['one']['some'].nil?
     => true
    

    似乎:

    if a['one']['some'].nil?
      a['one']['some']=Array.new
    end 
    

    就足够了。它是否正确?这对任何数据类型都是正确的吗?被定义为?在这种情况下需要吗?

    THX

3 个答案:

答案 0 :(得分:2)

你似乎混淆了两个概念。一种是定义变量,另一种是定义Hash键。由于哈希在某个时刻是变量,因此必须对其进行定义。

defined?(a)
# => nil

a = { }
# => {}

defined?(a)
# => "local-variable"

a.key?('one')
# => false

a['one'] = 'hello'
# => 'hello'

a.key?('one')
# => true

某些东西可以是一个密钥,同时nil,这是有效的。哈希没有定义或未定义的概念。关键是否存在是关键所在。

使用.nil?进行测试的唯一原因是要区分两个可能的非真值:nilfalse。如果您永远不会在该上下文中使用false,那么调用.nil?会产生不必要的冗长。换句话说,if (x.nil?)相当于if (x)提供的x永远不会是字面false

您可能想要使用的是||=模式,如果现有值为nilfalse,则会分配一些内容:

# Assign an array to this Hash key if nothing is stored there
a['one']['hello'] ||= [ ]

更新:根据Bruce的评论进行了编辑。

答案 1 :(得分:2)

我不得不深入挖掘Google的一些页面,但我最终从Ruby 1.9规范中找到了this useful bit

“在所有情况下,测试[定义?]是在不评估操作数的情况下进行的。”

所以正在发生的事情是:

a['one']['some']

并说“正在向'a'对象发送”operator []“消息 - 这是一个方法调用!”和定义的结果?那是“方法”。

然后当你检查nil?时,字符串“method”显然不是nil。

答案 2 :(得分:1)

除了@tadmans的回答,你在你的例子中实际做的是检查字符串"some"是否包含在字符串"hello"中,该字符串存储在位置{{ 1}}。

"one"

一个更简单的例子:

a = {}
a['one'] = 'hello'
a['one']['some'] # searches the string "some" in the hash at key "one"

这就是为什么b = 'hello' b['he'] # => 'he' b['ha'] # => nil 方法没有像您预期的那样返回defined?,而是nil