Cera
Cera

Reputation: 1909

Allowing for Ruby 1.9's hash syntax?

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

Answers (3)

The Who
The Who

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

the Tin Man
the Tin Man

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

Sean Hill
Sean Hill

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

Related Questions