短篇小说:
defined?(59[0][:whatever])
评估为真?" 长篇故事:
我最近遇到了一些让我失望的奇怪行为。
我正在开发一种方法来清理数据:
#Me washing input data:
def foo(data)
unless data && defined?(data[0]) && defined?(data[0][:some_param])
method2(data[0][:some_param])
else
freak_out()
end
end
我经常在各种垃圾数据中编写测试,以确保不会发生任何奇怪的事情:
describe "nice description" do
it "does not call method2 on junk data" do
expect(some_subject).to_not receive(:method2)
random_junk_data_array.each do |junk|
some_subject.foo(junk)
end
end
end
嗯,这里叫method2
。它发生在junk
是一个固定的时候。
我正在使用ruby 2.1.0
,我可以看到Fixnum
有一个#[]
方法可以获取该位置的位,很不错。
但为什么fixnum[0][:some_param]
被认为是defined
?
答案 0 :(得分:6)
defined?
表达式测试表达式是否引用任何可识别的内容(文字对象,已初始化的局部变量,当前作用域中可见的方法名称等)。如果无法解析表达式,则返回值为nil
。否则,返回值提供有关表达式的信息。
让我用一个例子来解释: -
defined?("a") # => "expression"
# this returns "method", as there is a method defined on the class String. So, the
# method invocation is possible, and this is a method call, thus returning `"method"`.
defined?("a".ord) # => "method"
# it return nil as there is no method `foo` defined on `"a"`,
# so the call is not possible.
defined?("a".foo) # => nil
现在谈到你的观点: -
正如您所说data[0]
提供Fixnum
个实例,当然Fixnum#[]
存在。因此fixnum_instance[:some_param]
也是一种有效的方法调用。它只是测试方法是否定义。如果已定义,它将告诉是这是"method"
表达式。否则nil
。实际上不会检查方法调用是否成功。
在Ruby中,除了nil
和false
之外,所有对象都有 truthy 值,因此作为字符串对象的"method"
也具有 truthy 价值,因此你的状况得到了成功。