Do...end vs. begin..end

I realize what the difference between these two block delimiters is, but
I can’t seem to put it in words. I realize that you only use do…end
when you are passing a block to a method, and that you can use
begin…end to create a block expression with a specific return value
(and rescue/ensure clauses). How would I explain to someone what the
difference is, though? I’ve been reading through “Programming Ruby” and
they just call both of them "block"s. Anyone with a better way of
explaining it?

-Kurt

do…end delimits a block, just like { … }. As far as I know, it can’t be
used as a stand-alone construct; the block has to be passed to a method.

irb(main):002:0> do
irb(main):003:1* puts “hello”
irb(main):004:1> end
SyntaxError: compile error

irb(main):005:0> 1.times do
irb(main):006:1* puts “hello”
irb(main):007:1> end
hello

begin…end groups together some expressions/statements. I’ve never seen
it used except when ‘rescue’ and/or ‘ensure’ are also required, because
Ruby’s other control structures (e.g. if … else … end, while … end) also
implicitly group statements together.

Note that ‘def’ also behaves like ‘begin’:

def mymethod(x)
puts “hello #{x}”
raise “roof”
rescue
puts “got exception”
end

mymethod(“world”)

#>> hello world
#>> got exception

Regards,

Brian.

···

On Sat, Jul 12, 2003 at 04:46:21AM +0900, Kurt M. Dresner wrote:

I realize what the difference between these two block delimiters is, but
I can’t seem to put it in words. I realize that you only use do…end
when you are passing a block to a method, and that you can use
begin…end to create a block expression with a specific return value
(and rescue/ensure clauses). How would I explain to someone what the
difference is, though? I’ve been reading through “Programming Ruby” and
they just call both of them "block"s. Anyone with a better way of
explaining it?

Hi Kurt,

I realize what the difference between these two block delimiters is, but
I can’t seem to put it in words. I realize that you only use do…end
when you are passing a block to a method, and that you can use
begin…end to create a block expression with a specific return value
(and rescue/ensure clauses). How would I explain to someone what the
difference is, though? I’ve been reading through “Programming Ruby” and
they just call both of them "block"s. Anyone with a better way of
explaining it?

do…end delimits a block, just like { … }. As far as I know, it can’t be
used as a stand-alone construct; the block has to be passed to a method.

That’s my (less-experienced) understanding, also.
There is a method in Kernel called ‘loop’ which provides:

loop do
puts ‘something’
break # on some condition
end

but the need rarely arises.

begin…end groups together some expressions/statements. I’ve never seen
it used except when ‘rescue’ and/or ‘ensure’ are also required, because
Ruby’s other control structures (e.g. if … else … end, while … end) also
implicitly group statements together.

[…]

Regards,

Brian.

I’ll live dangerously and say that begin…end are there for when you
have the requirement, whereas do…end is required almost immediately
and is very common in both its forms (the brace form, as Brian
mentioned above, is [#] identical).

[#] do...end has lower precedence than {...} when binding to its method. "Programming Ruby - PragProgs" ref: Blocks, Closures, and Proc Objects

daz

···

“Brian Candler” B.Candler@pobox.com wrote:

On Sat, Jul 12, 2003 at 04:46:21AM +0900, Kurt M. Dresner wrote:

There’s an RCR (can’t find it…) for making ‘do’ behave like that as well:

collection.each do |elt|
# …
rescue
# …
end

Oh, how nice that would be!

Gavin

···

On Sunday, July 13, 2003, 3:08:11 AM, Brian wrote:

[…]

Note that ‘def’ also behaves like ‘begin’:

def mymethod(x)
puts “hello #{x}”
raise “roof”
rescue
puts “got exception”
end

mymethod(“world”)

#>> hello world
#>> got exception

That’s my (less-experienced) understanding, also.
There is a method in Kernel called ‘loop’ which provides:

loop do
puts ‘something’
break # on some condition
end

but the need rarely arises.

well, that is the same thing…try with

loop {
}

this is one of those typical ‘other language in ruby’ thing :slight_smile:

I’ll live dangerously and say that begin…end are there for when you
have the requirement, whereas do…end is required almost immediately
and is very common in both its forms (the brace form, as Brian
mentioned above, is [#] identical).

just forget ‘block’:
do…end delimits the code for a Proc object
begin…end enclose a part of your code, mainly to be used with
rescue/ensure statements

my 2c

···

il Sat, 12 Jul 2003 19:13:28 +0100, “daz” dooby@d10.karoo.co.uk ha scritto::

loop do
end

well, that is the same thing…try with

loop {
}

this is one of those typical ‘other language in ruby’ thing :slight_smile:

I haven’t come from a HLL. I took the choice to use
do…end for all multi-line blocks.
I’d use loop {…} if it was short enough to fit on one line.

IMO, it’s more likely an ‘other language in ruby’ thing
to feel as though ‘loop do’ is a double operation
-or-
to leave a trailing brace on a line of its own ?

just forget ‘block’:
do…end delimits the code for a Proc object

my 2c

Then I’d ask you to double your money and use your description
to cover what this does:

proc do
end

I’m comfortable with the description that it converts
a block into a Proc object.

daz

···

“gabriele renzi” surrender_it@remove.yahoo.it wrote:

il Sat, 12 Jul 2003 19:13:28 +0100, “daz” dooby@d10.karoo.co.uk > ha scritto::

(not forgetting ‘block’ in too much of a hurry :slight_smile:

damn, you’re rigth :slight_smile:

I think that could become
‘the proc method takes in input the code from a Proc object delimited
from do…end and generates the relative Proc (like Proc::new)’

But now I feel that this way is ugly…

···

il Sun, 13 Jul 2003 05:17:36 +0100, “daz” dooby@d10.karoo.co.uk ha scritto::

just forget ‘block’:
do…end delimits the code for a Proc object

my 2c

Then I’d ask you to double your money and use your description
to cover what this does:

proc do
end

I’m comfortable with the description that it converts
a block into a Proc object.