Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby do/end vs braces

Tags:

Why does this map expression produce different results depending on whether I use braces or do/end?

a = [1,2,3,4,5]   p a.map { |n|     n*2 }   #=> [2,4,6,8,10]   p a.map do |n|     n*2 end   #=> [1,2,3,4,5] 
like image 856
Grandpa Avatar asked Apr 01 '11 12:04

Grandpa


People also ask

Do-End vs brackets Ruby?

From Programming Ruby: Braces have a high precedence; do has a low precedence. If the method invocation has parameters that are not enclosed in parentheses, the brace form of a block will bind to the last parameter, not to the overall invocation. The do form will bind to the invocation.

Do vs {} Ruby?

There are two ways of defining a block in Ruby: The first is using the do.. end keyword, the other is using a pair of curly braces. Do.. end block is mainly used when defining a block of code that spans multiple lines, while curly braces {} are used when defining a block of code that spans a single line.

What do brackets mean in Ruby?

The square brackets [ ] are used to initialize arrays. The documentation for initializer case of [ ] is in ri Array::[] The curly brackets { } are used to initialize hashes.

What is a block argument in Ruby?

What is a ruby block? A ruby block is one or more lines of code that you put inside the do and end keywords (or { and } for inline blocks). It allows you to group code into a standalone unit that you can use as a method argument.


2 Answers

That's because the second line is interpreted as:

p(a.map) do ... end 

instead of:

p(a.map do ... end) 

The grammar is ambiguous in this case and do doesn't seem to bind as strongly as {.

like image 174
DarkDust Avatar answered Oct 14 '22 04:10

DarkDust


That has to do with the difference in associativity of the { character and the do keyword.

In the first case, the block is interpreted as a block argument to the map function. The result of the map function is the argument to the p function.

In the second case, the block is interpreted as a block argument to the p function, while the a.map is interpreted as the first argument to the p function. Since a.map evaluates to a, this prints the original array. The block is effectively ignored in this case.

like image 45
Confusion Avatar answered Oct 14 '22 04:10

Confusion