Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are there "rules" for Ruby syntactic sugar?

Tags:

ruby

I'm learning the basics of Ruby (just starting out), and I came across the Hash.[] method. It was introduced with

a = ["foo", 1, "bar", 2]
=> ["foo", 1, "bar", 2]
Hash[*a]
=> {"foo"=>1, "bar"=>2}

With a little thought, I figured out that Hash[*a] is equivalent to Hash.[](*a) or Hash.[] *a. My question is why that's the case. What is it that lets you put the *a inside the square brackets, and is there some kind of rule for where and when else "it" can be used?

Edit: My wording seems to be causing some confusion. I'm not asking about the array expansion. I get that. My question is basically: if [] is a method name, why is it okay to put arguments inside the brackets? It seems almost--but not quite--like saying that if you have a method Foo.dood, and you wanted to pass the string "hey" to it, then you could write Foo.do"hey"od.

like image 864
Ryan Stewart Avatar asked Oct 09 '11 18:10

Ryan Stewart


3 Answers

Hash["a", "b", "c", "d"] is equivalent to Hash.[]("a", "b", "c", "d"). Almost everything in Ruby is a method call. 5 + 5 is equivalent to 5.+(5).

Given a = ["a", "b", "c", "d"] Hash[*a] is equivalent to Hash["a", "b", "c", "d"], which in turn is equivalent to Hash.[]("a", "b", "c", "d"). Similarly, foo(*a) is equivalent to foo("a", "b", "c", "d") This is called the explode operator, and allows sending an array to a method and have each item in the array count as one argument to the method, instead of sending the array to the method as the first argument.


To specifically answer your update, there's nothing special that lets you put *a inside the brackets. The brackets is just sugar for a normal method call. The only "special" thing here is that you can send *a to any method.

like image 142
August Lilleaas Avatar answered Oct 18 '22 21:10

August Lilleaas


There are a couple methods that ruby lets you call in a special way. These are the [] as you mentioned, the +, -, == and the like as someone else mentioned. Another important example are methods of the form something=(value) which can be called with object.something = value and allow you to create accessors.

Edit:

Fun fact 1: if you define a + method you get += for free.

Fun fact 2: if you define a <=> you get all comparison methods, courtesy of Comparable

like image 30
Paweł Obrok Avatar answered Oct 18 '22 21:10

Paweł Obrok


I think that Ruby's syntax is defined in parse.y for YARV Ruby.

like image 24
Andrew Grimm Avatar answered Oct 18 '22 22:10

Andrew Grimm