Braces vs do/end in 1.9

Contrived example derived from someone else I know trying to learn the
language…

In 1.8.x the two fragements below work identically and generate the same
output.

In 1.9.x these two fragments have different behavior between each other,
and fragment B yields different output than fragement A

In 1.9, the second fragment returns the iterator object rather than the
capitalized word.

What’s the intent of changing the behavior?

// A
myarray = [“mickey”, “minnie”]
puts myarray.collect {
|word|
word.capitalize
}

// B
myarray = [“mickey”, “minnie”]
puts myarray.collect do
|word|
word.capitalize
end

– gw

Greg W. wrote in post #1006491:

Contrived example derived from someone else I know trying to learn the
language…

In 1.8.x the two fragements below work identically and generate the same
output.

puts RUBY_VERSION

myarray = [“mickey”, “minnie”]
puts myarray.collect {|word| word.capitalize}

myarray = [“mickey”, “minnie”]
puts myarray.collect do |word|
word.capitalize
end

–output:–
1.8.6
Mickey
Minnie
mickey
minnie

–output:–
1.8.7
Mickey
Minnie
mickey
minnie

–output:–
1.9.2
Mickey
Minnie
#Enumerator:0xa089b34

Braces bind tighter than do…end, and in ruby 1.9 arr.collect returns
an Enumerator object, which puts prints out before the do…end block
can do its thing.

In 1.9, the second fragment returns the iterator object rather
than the capitalized word.

What’s the intent of changing the behavior?

So that you can pass around Enumerator objects, or chain enumerators
together:

7stud – wrote in post #1006513:

So that you can pass around Enumerator objects, or chain enumerators
together:

myarray = [1, 2, 3, 4, 5]
e = myarray.enum_for(:each_slice, 3)

def do_stuff(enum)
c = enum.enum_for(:cycle)
3.times {p c.next}
end

do_stuff(e)

–output:–
[1, 2, 3]
[4, 5]
[1, 2, 3]

7stud – wrote in post #1006513:

puts 10 do |x|
puts ‘hello’
end

–output:–
10

Remember a block is like a hidden argument to a method(despite the
claims to the contrary). If the method doesn’t yield to the block then
the block isn’t used. After all you can write a method that takes 10
arguments, and the method can ignore 9 of the arguments if you want.
puts() is ignoring the block.

Here’s a solution I offered to an earlier post that employs an
enumerator:

http://www.ruby-forum.com/topic/1701300#new

hi Greg -

well, using ruby 1.8.7 (2010-01-10 patchlevel 249) [i486-linux] i
don’t get identical output from the two examples…

//A
=> Mickey
Minnie

//B
=> mickey
minnie

certainly interesting… from what i understand, braces and do/end
are not exactly the same - braces have a higher precedence and bind in a
different way. check out this post -

  • j

7stud – wrote in post #1006523:

puts() is ignoring the block.

In other words, with braces the block binds to the collect() method, but
with do…end the block binds to the puts() method. Then collect()
yields to the block, but puts() ignores it.