Hal Fulton wrote:

> Paul Lutus wrote:
>> 
>> "do" reads from a list of items and provides them to its controlling
>> block:
>> 
>> These two forms are interchangeable. One can argue that "do" is an
>> implicit "{ ... }" block, or the reverse. But the point is "do" receives
>> items and operates on them one at a time, then exits when its stream is
>> empty.
> 
> Not strictly true. Reemember that the iteration comes from the fact
> that the each method is invoking the block multiple times.

Yes, you are right (an I am quite wrong in the above quotation). The "do ...
end" block is simply a closure with an alternate syntax, and the calling
method provides the data and any repetition that may exist.

---------------------------------------------------

#! /usr/bin/ruby

def my_funct
   1.upto(8) do |x|
      yield x
   end
end

my_funct do |item|
   puts item
end

(or, equivalently)

my_funct { |item|
   puts item
}

So it appears that the syntactic role played by "do" is that it receives and
acts on the data fed to it by the calling method, once (barring any
repetitions internal to the do ... end block). IOW it is a closure block,
nothing more. Any looping is in the hands of the calling method.

So it appears the only difference between "do ... end" and "begin ... end"
is that "begin ... end" doesn't receive data from a caller.

The moment I realized I was wrong was when I fed the do ... end block "nil"
repeatedly, and it processed it anyway. It wasn't going to skip over a
false input, so the entire process is in the hands of the calling method.

-- 
Paul Lutus
http://www.arachnoid.com