Reputation: 1909
Although I've been using Ruby 1.9 for a while, I only recently discovered the newer hash syntax that's now supported:
settings = {
host: "localhost",
port: 5984
}
As opposed to:
settings = {
"host" => "localhost"
}
I like its similarity to JavaScript's object noation, and looks a bit like JSON, so I'll probably switch to using it with all my libraries, but I still want to support other users and my own projects which assume the old syntax.
So it really comes down to a fairly simple question of having to test for both symbols and strings. Is there an easy way to do both of these lines as one?
return true if settings["host"] and settings["db"]
return true if settings[:host] and settings[:db]
Upvotes: 3
Views: 5353
Reputation: 6622
ActiveSupport (from Rails) offers HashWithIndifferentAccess. You will need to explicitly use it instead of a standard Hash.
Beware though, a quote from the class itself:
This class has dubious semantics and we only have it so that people can write params[:key] instead of params[‘key’] and they get the same value for both keys.
Upvotes: 3
Reputation: 160621
So it really comes down to a fairly simple question of having to test for both symbols and strings. Is there an easy way to do both of these lines as one?
return true if settings["host"] and settings["db"]
return true if settings[:host] and settings[:db]
I'm not sure what you're really asking, because this doesn't seem totally related to the original title, but try:
# somewhere you get the values you are going to need to look up...
host = 'foo'
db = 'bar'
# then code goes by...
return true if settings[host.to_sym] and settings[db.to_sym]
# later you assign a symbol to one of the keys:
host = :foo
# more code goes by...
return true if settings[host.to_sym] and settings[db.to_sym]
It's all the same. Let Ruby covert from strings to symbols as necessary.
This works because:
'foo'.to_s # => "foo"
:foo.to_s # => "foo"
'foo'.to_sym # => :foo
:foo.to_sym # => :foo
You pick whether you're going to use symbols or strings for hash keys and let Ruby sort it out.
Upvotes: 1
Reputation: 15056
Even in Ruby < 1.9, you could use symbols for keys. For example:
# Ruby 1.8.7
settings = { :host => "localhost" }
puts settings[:host] #outputs localhost
settings.keys[0].class # => Symbol
Ruby 1.9 changes the way that you create hashes. It takes the key and converts it to a symbol for you, while eliminating the need for a hash rocket.
# Ruby 1.9.2
settings = { host: "localhost" }
settings[:host] # => "localhost"
settings.keys[0].class # => Symbol
In both cases, if I try to access settings[:name]
with settings["name"]
, I'm going to get nil. All Ruby 1.9 does is allow for a new way of creating hashes. To answer your question, you cannot, as far as I know, use the new {key: value}
syntax if you want backwards compatibility with Ruby 1.8.
Upvotes: 5