Hash has_key? syntax
Solution 1
There are strings and there are symbols. A string is not a symbol.
These hashes contain a symbol as a key:
{key: "value"}
{:key => "value"}
This hash contains a string as a key:
{"key"=>"value"}
That's why your tests behave like they do.
Rails has a wrapper for Hash, called HashWithIndifferentAccess. If you have one of those, you can access values by either strings or symbols. But for regular hashes, there's distinction.
require "active_support/core_ext"
h = {key: "value"}.with_indifferent_access
h.has_key?(:key) # => true
h.has_key?("key") # => true
Solution 2
If you observe while you assign the hashes, in IRB they're like this:
2.0.0p247 :014 > a = {key:"values"}
=> {:key=>"values"}
2.0.0p247 :015 > b = {"key" => "values"}
=> {"key"=>"values"}
2.0.0p247 :016 > c = {:key => "value"}
=> {:key=>"value"}
We can see that a
and c
are the same, other than the syntax used for assigning. The syntax used for c
is I guess the old syntax.
a = {key:"values"}
is the syntax introduced in the latest Ruby version. In both hash a
and c
, the key is a
symbol.
"The Difference Between Ruby Symbols and Strings" explains the difference between string and symbol,
whereas in hash b
the key value is a string. Apparently its value is "key". The major difference is the value of key for hash b
is mutable while it's not true in case of hash a
.
Micka
Updated on June 04, 2022Comments
-
Micka almost 2 years
I have three Hashes:
a = {key:"value"} b = {"key"=>"value"} c = {:key=>"value"}
And these results:
a.has_key?("key") # => false b.has_key?("key") # => true c.has_key?("key") # => false
My questions are:
- Why? What is this behavior?
- How can I get
a
,b
andc
to returntrue
using the same syntax for all of them?