为什么我会在三元条件下得到意想不到的结果?

时间:2013-09-26 17:17:28

标签: ruby

任何人都可以向我解释这个结果:

(trad = {foo: "Foo", bar:"Bar"}).has_key? :foo ? trad[:foo] : :foo
=> false

我期待它回归:

=> "Foo"

2 个答案:

答案 0 :(得分:8)

(trad = {foo: "Foo", bar:"Bar"}).has_key? :foo ? trad[:foo] : :foo

就像:

(trad = {foo: "Foo", bar:"Bar"}).has_key? (:foo ? trad[:foo] : :foo)

:foo ? trad[:foo] : :foo评估为"Foo",因为:foo被视为真值。

(trad = {foo: "Foo", bar:"Bar"}).has_key? "Foo"会产生false,因为没有“Foo”键。


使用以下(覆盖周围括号的优先顺序)来获得预期结果:

>> ((trad = {foo: "Foo", bar:"Bar"}).has_key? :foo) ? trad[:foo] : :foo
=> "Foo"

Hash#fetch(key, default)似乎更合适:

>> {foo: "Foo", bar:"Bar"}.fetch(:foo, :foo)
=> "Foo"
>> {foo: "Foo", bar:"Bar"}.fetch(:baz, :baz)
=> :baz

答案 1 :(得分:1)

由于缺少括号,应用程序丢失了......

(trad = {foo: "Foo", bar:"Bar"}).has_key? :foo  ? trad[:foo] : :foo  # => false
(trad = {foo: "Foo", bar:"Bar"}).has_key?(:foo) ? trad[:foo] : :foo  # => "Foo"

我要小心写这样的代码:

(trad = {foo: "Foo", bar:"Bar"})

这不是惯用语,所以请使用:

trad = {foo: "Foo", bar:"Bar"}
trad.has_key?...

原因是,在恐慌时,就像凌晨2:45,当你的编码合作伙伴接到一个系统中断的电话,因为他正在通话,并潜入代码时,很难找到这项任务。

在代码审查中,我建议这样做:

trad = {foo: "Foo", bar:"Bar"} 
trad.has_key?(:foo) ? trad[:foo]
                    : :foo        # => "Foo"

注意:这仅适用于Ruby 1.9 +。

所有人都说,我强烈建议您使用fetch作为recommended by @falsetru