Hash or not a Hash?!

In Rails, we can see the following for example (They are separate here):

:x=>"new_x"

:y=>{:x=>X.new}

From Ruby, I know that a hash has to be between { }, and the key is on the left of => and the value to the right.

But, in the above examples we are seeing => everywhere! What is => ? Is it like = (assignment operator)?

Thanks.

:x=>"new_x"

Here x is the key and "new_x" is the value.

:y=>{:x=>X.new}

Here y is the key and another hash, {:x => X.new}, is the value. And within this hash again, x is the key and X.new is the value.

Abder-Rahman Ali wrote:

In Rails, we can see the following for example (They are separate here):

:x=>"new_x"

:y=>{:x=>X.new}

From Ruby, I know that a hash has to be between { }

But you are wrong. The braces can be omitted when there is no ambiguity.

Any time you see =>, a Hash is involved. That syntax has no other use.

I think what's confusing him is that the outer hash isn't within {}s -- he doesn't realize that the {}s aren't *always* necessary, that there are implicit hashes in some method calls.

-Dave

Dave Aronson wrote:

�> :x=>"new_x"

Here x is the key and "new_x" is the value.

:y=>{:x=>X.new}

Here y is the key and another hash, {:x => X.new}, is the value. And within this hash again, x is the key and X.new is the value.

More accurately the symbol :y is the key (splitting hairs)...

I think what's confusing him is that the outer hash isn't within {}s -- he doesn't realize that the {}s aren't *always* necessary, that there are implicit hashes in some method calls.

Technically speaking Marnen's reply ("The braces can be omitted when there is no ambiguity.") is more accurate.

I also wanted to point out that there is a new "optional" syntax for hash key/value pairs introduced in Ruby 1.9:

{ :x: y } same as { :x => y } same as :x: y same as :x => y

So what's the business about ambiguity?

my_obj.my_method(:x => y, :a => b)

Was the intent of the above to call my_method with a single hash with two keys and two values, or to pass two single key hashes to my_method?

Sometimes the {} are required to remove ambiguity:

my_obj.my_method({ :x => y, :a => b })

1 hash argument containing 2 key/value pairs

my_obj.my_method({ :x => y }, { :a => b })

2 hash arguments each with a single key/value pair

my_obj.my_method([ { :x => y }, { :a => b } ])

1 array argument containing two hash elements, each having a single key/value pair

my_obj.my_method([ { :x => y, :a => b } ])