Reputation: 1376
Can anyone explain to me this result please:
(trad = {foo: "Foo", bar:"Bar"}).has_key? :foo ? trad[:foo] : :foo
=> false
I expected it to return:
=> "Foo"
Upvotes: 2
Views: 91
Reputation: 160551
For want of parenthesis the app was lost...
(trad = {foo: "Foo", bar:"Bar"}).has_key? :foo ? trad[:foo] : :foo # => false
(trad = {foo: "Foo", bar:"Bar"}).has_key?(:foo) ? trad[:foo] : :foo # => "Foo"
I'd be careful writing code like this:
(trad = {foo: "Foo", bar:"Bar"})
It's not idiomatic, so use:
trad = {foo: "Foo", bar:"Bar"}
trad.has_key?...
The reason is, in times of panic, like at 2:45 AM when your coding partner gets a call about a system outage because he's on call, and dives into the code, that assignment could be hard to find.
In a code review I'd suggest something like this over the other:
trad = {foo: "Foo", bar:"Bar"}
trad.has_key?(:foo) ? trad[:foo]
: :foo # => "Foo"
Note: This only works on Ruby 1.9+.
That all said, I'd highly recommend using fetch
as recommended by @falsetru.
Upvotes: 1
Reputation: 368894
(trad = {foo: "Foo", bar:"Bar"}).has_key? :foo ? trad[:foo] : :foo
is like:
(trad = {foo: "Foo", bar:"Bar"}).has_key? (:foo ? trad[:foo] : :foo)
:foo ? trad[:foo] : :foo
is evaluated to "Foo"
because :foo
is treated as truth value.
(trad = {foo: "Foo", bar:"Bar"}).has_key? "Foo"
yields false
because there's no "Foo" key.
Use following (override precedence by surrounding parentheses) to get the expected result:
>> ((trad = {foo: "Foo", bar:"Bar"}).has_key? :foo) ? trad[:foo] : :foo
=> "Foo"
Hash#fetch(key, default)
seems more appropriate:
>> {foo: "Foo", bar:"Bar"}.fetch(:foo, :foo)
=> "Foo"
>> {foo: "Foo", bar:"Bar"}.fetch(:baz, :baz)
=> :baz
Upvotes: 8