Ruby Blocks and Blocks «

Code: , , ,

I’m reading Programming Ruby: 2nd Ed. and an example on page 57 has captured my attention. (Code slightly modified for brevity)

"3 4\n5 6\n7 8".each do |line|
v1, v2 = line.split
print Integer(v1) + Integer(v2), " "

The book is just explaining to Perl coders that you have to call Integer() to convert strings to ints, but I see an interesting opportunity to restructure the code.

"3 4\n5 6\n7 8".collect do |line|
end.each do |a, b|
print Integer(a) + Integer(b), " "

My brain is nagging me that there’s a fundamental concept at work in this change, but I can’t quite put my finger on it. It’s not just that I’m building an array in the middle or that it evaluates differently (after producing identical output), it’s that it looks something like nested fuction calls. It feels like a more a functional style of programming, but that’s not quite all.

I’m compelled to write this as a block yielding to a block, though it doesn’t compile:

"3 4\n5 6\n7 8".collect { |line| yield line.split } { |a, b| print Integer(a) + Integer(b), " " }

Any thoughts? Am I just being weird, or can anyone put better words to it?


  1. “I’m compelled to write this as a block yielding to a block, though it doesn’t compile..”

    Seem’s like you want to do ‘something’ with the result of line.split which is again ‘iterator’ like. No?

    After all, it returns two values, which are used only in the next line.

    How’s about:
    “3 4\n5 6\n7 8″.each do |line|
    print line.split.inject(0) { |prev, a| prev + Integer(a) }, “”

    Although, along the lines you were thinking – you could do something like a ‘nested function call’ using a proc object (like a python lambda):

    “3 4\n5 6\n7 8″.each do |line|
    print proc {|a,b| Integer(a) + Integer(b) }.call(*line.split), “”

    But i think inject is sweeter.

  2. Hmm, i think i missed your point though: “it looks something like nested fuction calls.” — !
    I like to think of it as chaining rather than nested – the way that the ‘.’ evaluates from left to right.

Leave a Reply

Your email address will not be published.