Why do these two code blocks have different behavior?

I am not a total newbie in ruby, but I am still hazy on how things
like blocks, proc objects and contexts work under the covers. I have
experience with Lisp lambdas, so feel free to get technical.

My question is - why do the following two functions have different
behavior?

require “pp”

@@a = [1, 2, 3]

def q1
@@a.inject(0) {|sum, x|
pp x
return sum + x
}
end

def q2
@@a.inject(0) {|sum, x|
pp x
sum + x
}
end

On May 5, 2007, at 12:45 AM, yuricake wrote:

return sum + x
}
end

def q2
@@a.inject(0) {|sum, x|
pp x
sum + x
}
end

Because the return statement terminates the method q1 and not the
block that is associated with the call to inject. You are effectively
bailing out of inject on the first iteration.

In q2, when control runs off the end of the block, control is returned
to inject, which can continue with its iterations.

Gary W.

The return statement is causing an early break.
it doesn’t do what you think it does (what it does in other languages)
The desired behavior is in q2.
Ruby automatically returns the result of the last statement in the
block.
Also, a clue that you’re thinking in another language is the curly
braces.
Ruby style is to use curly braces for one-liners and do-end for multi-
line blocks.

def q1
@@a.inject(0) {|sum, x|
pp x
return sum + x
}
end
I’ll add one thing to the other’s explanations: ‘next’ does what you
thought ‘return’ was doing: it terminates the block, returning the value
given as argument

def q1
@@a.inject(0) do |sum, x|
pp x
next sum + x
end
end

will also work

On 5/5/07, yuricake [email protected] wrote:

def q1
@@a.inject(0) {|sum, x|
pp x
return sum + x
this return will jump out of the method altogether. So the method will
print x once, and then return sum + x, that is 0 + 1 = 1
}
end

def q2
@@a.inject(0) {|sum, x|
pp x
sum + x
}
end

in this case, there’s no return to interrupt the inject loop, so the
sum will be calculated properly and return value from the method will
be the return value of inject, i.e. the sum 6.