Ruby Newbie (ooh, that rhymes!) - When do I use do/end, when {}?

G

Glenn

Hello all

First some waffle as this is my first post...

I picked up on Ruby just a few days ago. Somebody in an unrelated
thread on an unrelated forum mentioned "A Ruby programmer is a happy
programmer". So I decided to find out more.

My usual work is currently with Visual Basic and PL/SQL, but I like to
have a general purpose scripting language for all those extra jobs
that VB would be a bit too much of a sledgehammer for!

I've tried Perl (hateful messy syntax, gave up)
Looked at Python... not for me
Don't like VBScript because of it's "slightly different to VB" nature
(and besides, it's Windows-only and I use both Windows and Solaris at
work)
etc.

Ruby, as I'm sure you lot have already have discovered, really hits
the spot. I read somewhere of it being called "a delightful
language", and it's very true. Nice syntax, nice and clean OO
features, everything I could want and easy to get started with. So
please, Matz and everybody else involved, stick with it, make it even
more feature-rich (but don't damage the core syntax!), and let me
throw VB away forever!!! (well, I can live in hope!).

Anyway, to my first question....


I've read the User Guide and other docs on the net, but I'm a little
unsure as to whether I can ALWAYS substitute the DO/END with curly
brackets for a block? For example, I've only ever seen referenced to
hash definitions using curlies. What's the rule here? Is it purely
down to preference?
 
J

Jean-Hugues ROBERT

I've read the User Guide and other docs on the net, but I'm a little
unsure as to whether I can ALWAYS substitute the DO/END with curly
brackets for a block? For example, I've only ever seen referenced to
hash definitions using curlies. What's the rule here? Is it purely
down to preference?

Welcome.
You can always substitute the DO/END with curly brackets for a block.
However, in some cases, you may need some extra parenthesis.
This is due to {} having a different precedence than do/end and
correlated impact on associativity.

And Yes, Ruby Rocks.

Yours,

Jean-Hugues
 
M

Mark Hubbart

I've read the User Guide and other docs on the net, but I'm a little
unsure as to whether I can ALWAYS substitute the DO/END with curly
brackets for a block? For example, I've only ever seen referenced to
hash definitions using curlies. What's the rule here? Is it purely
down to preference?

While there is some amount of preference involved, there is a general
rule that most Ruby programmers (and matz, I believe) agree on:
brackets for one-line blocks, do...end for longer blocks. ie:

5.times {|n| puts n }

5.times do |n|
print "bingo! " if n == 3
puts n
end

There are skirmishes sometimes between people who like to use all
brackets all the time, and those who use the above method. :) But this
is the most common way, and you'll find it mostly like that in the
standard library.

HTH,
--Mark
 
M

Mark Hubbart

Welcome.
You can always substitute the DO/END with curly brackets for a block.
However, in some cases, you may need some extra parenthesis.
This is due to {} having a different precedence than do/end and
correlated impact on associativity.

yes, in ambiguous situations, it can require parent either way. For
example, if you write

array.inject num.to_f {|a,b| a * b }

Ruby assumes you want the block to be passed to the num.to_f method
call. This is probably not what you want, though. To solve that one,
put parens around the num.to_f call:

array.inject( num.to_f ) {|a,b| a * b }

That will work properly. likewise, there can be similar problems with
do...end:

obj.foo array.map do |item|
p item
item * 2
end

This snippet will hand the block to obj.foo, which is probably not what
you want. to solve it, you could do this:

obj.foo( array.map do |item|
p item
item * 2
end )

... but that's ugly. you would probably want to just break down and do
it in two steps:

a = array.map do |item|
p item
item * 2
end
obj.foo a

or convert it to a one liner:

obj.foo array.map{|item| p item; item * 2 }

cheers,
--Mark
 
J

Jim Weirich

Mark said:
While there is some amount of preference involved, there is a general
rule that most Ruby programmers (and matz, I believe) agree on: brackets
for one-line blocks, do...end for longer blocks. ie:

I've heard that general advice, and even followed it for a while. I
finally gave up on it because many one liners grow into multiline
blocks, and it was just annoying to switch from {} to do/end when that
happened. Plus the style choice wasn't conveying any additional
information, so I dropped it and went back to a "whatever looks good" style.

Just recently I've been trying out the following guidelines:

o If the block returns a value, use {}
o if the block doesn't return a value, use do/end

So far I like the way it is turning out. The style choice helps to
convey some of the intent of the programmer.

I offer it here for others to try. If they like it, fine. If it
doesn't work for you, no problem either.
 
J

James Britt

Jim said:
I've heard that general advice, and even followed it for a while. I
finally gave up on it because many one liners grow into multiline
blocks, and it was just annoying to switch from {} to do/end when that
happened. Plus the style choice wasn't conveying any additional
information, so I dropped it and went back to a "whatever looks good"
style.

Just recently I've been trying out the following guidelines:

o If the block returns a value, use {}
o if the block doesn't return a value, use do/end


{ ... } means less typing, plus brace matching in Vim.

Yeah, I know that the ruby plugin for Vim will auto-type do/end for me,
but I also find the braces visually cleaner.

James
 
G

Gennady Bystritsky

As somebody has mentioned already it is not only preference, but also
precedence rules ({} sticks better than do...end, meaning higher
precedence).
While there is some amount of preference involved, there is a general
rule that most Ruby programmers (and matz, I believe) agree on:
brackets for one-line blocks, do...end for longer blocks. ie:

5.times {|n| puts n }

There's also another usage some people, including myself, agree on:
do...end for blocks that actually DO stuff, like in Array#each,
File.open, Integer#times (Mark, sorry for contradiction ;-)), etc.; {}
for blocks that define conditions, like in map, select/reject, sort,
etc.


Sincerely,
Gennady Bystritsky
 
G

Gavin Sinclair

{ ... } means less typing, plus brace matching in Vim.
Yeah, I know that the ruby plugin for Vim will auto-type do/end for me,
but I also find the braces visually cleaner.


I agree with Jim Weirich, and would just like to point out:
* Vim will %-match do/end as well as {}
* do/end is *easier* to type than {} in terms of wear and tear on
my poor fingers

Gavin
 
J

James Britt

Gavin said:
I agree with Jim Weirich, and would just like to point out:
* Vim will %-match do/end as well as {}

That's good news. Is this in the current Rub Vim scripts? I have some
version of ruby.vim/ruby-macros , but it does not % match do/end for me.

* do/end is *easier* to type than {} in terms of wear and tear on
my poor fingers


Ok, well how 'bout this: braces use fewer characters, so you save disk
space.


James
 
G

Glenn

Gennady Bystritsky said:
There's also another usage some people, including myself, agree on:
do...end for blocks that actually DO stuff, like in Array#each,
File.open, Integer#times (Mark, sorry for contradiction ;-)), etc.; {}
for blocks that define conditions, like in map, select/reject, sort,
etc.

And this would include curlies for hash definitions then?

I like the idea of standardising on do/end for multi-line blocks and
curlies for single lines. That makes sense. I like the readability
of using do/end - seems to make for nicer code.

Thanks all, you've helped a lot. Ruby certainly does rock!
 
J

Jean-Hugues ROBERT

Whether do/end is easier to type than {} is rather subjective... from
personal experience, I tend towards {} because I can type {} in an
easy stroke (hold down shift, roll fingers over { and }), and I can
then fill in. But I digress - I'm just talking of personal experience.

To tackle the answer from a different angle - my guess is that
programmers who come from a C/Java/Perl environment would lean towards
{}, and programmers from a shell scripting environment may tend
towards do/end, simply because of habit.

I come from Pascal, so I tend to do/end. So you are probably right
about the habit.

The sad thing is that this style issue really matters a lot for people.
As a result rejecting either option is religious and accepting both is
agnostic. Once again religion leads to war. Really sad.

Ruby: a peaceful language (and fun too).

Yours,

Jean-Hugues
 
D

David Alan Black

Hi --

Jean-Hugues ROBERT said:
I come from Pascal, so I tend to do/end. So you are probably right
about the habit.

I come from Ruby :) and I find myself tending to use {} for shorter
blocks and/or blocks that are chained:

a.select {blah}.map {blah} # etc.

partly because "do blah end.map do blah end" sort of runs together
visually.

My instinct was always to space the dots apart in such cases:

a.select {blah} .map {blah}

though I've recently noticed that this isn't done in the Ruby
distribution, which I generally use as my style reference.
The sad thing is that this style issue really matters a lot for people.
As a result rejecting either option is religious and accepting both is
agnostic. Once again religion leads to war. Really sad.

Heavens. I think we were just chatting about it. Here on
ruby-talk/clr we still do that sometimes :)


David
 
K

Kristof Bastiaensen

There's also another usage some people, including myself, agree on:
do...end for blocks that actually DO stuff, like in Array#each,
File.open, Integer#times (Mark, sorry for contradiction ;-)), etc.; {}
for blocks that define conditions, like in map, select/reject, sort,
etc.

I also like to use {} when I know the block will still exist
after the method finishes (for example in signal callbacks or
lambda expressions).
This way you can see clearly what belongs together.

Anyway calling it a rule I find be a bit to strong, I believe
it is anyone's one choice which one he/she prefers to use.

Kristof
 
S

Stephan Kämper

Hi David, Robert & all...

8< snip ...

....and certainly depends on the keyboard layout. On my (German) keyboard
for example '{' is reached with [AltGr]-7 and I get '}' with [AltGr]-0
(which, IMO, isn't too comfortable).

Nevertheless I prefer using the {} pair. Perhaps because I used C++ and
the like before I switched to Ruby. But then, I used Pascal too (but
loooong ago).

8< snip ...

??? I don't think we're at war.
Heavens. I think we were just chatting about it. Here on
ruby-talk/clr we still do that sometimes :)

Yes. And that's great.

It's a matter of personal style, preferences, hisotry, momentum (in a
way), instinct and may be keyborad layout and (typing) lazyness.

I wouldn't accept neither of these as a reason for war, heatet debates
or anything like that.

I like programming, I like Ruby - I combine these and be happy.
(And I somewhat like the idea of taoism, which you might have noticed...)

Happy rubying

Stephan
 
M

Mark Hubbart

Heavens. I think we were just chatting about it. Here on
ruby-talk/clr we still do that sometimes :)

I admit, I hadn't realized the situation was a complex as it is. I had
seen where people used only brackets, so I mentioned that, not knowing
how many different styles I was leaving out :) It's probably because
I've only been here a few months, and haven't seen all the discussion.
Still, it's very interesting to me to hear all the different rules
people use for their code blocks.

A very informative thread for me. I *hope* it didn't sound like a flame
war :)

--Mark
 
J

James Britt

Jean-Hugues ROBERT said:
At 15:12 02/05/2004 +0900, you wrote:
The sad thing is that this style issue really matters a lot for people.
As a result rejecting either option is religious and accepting both is
agnostic. Once again religion leads to war. Really sad.

I don't see religion as having anything to do with this; I follow the
principal of IDGARA:

I Don't Give A Rat's Ass


James
 
J

Jim Menard

"Mieux vaut prévenir que guérir"
"It's better to prevent than to cure".

The English version: "An ounce of prevention is worth a pound of cure."

I can't wait until we go metric here in the USA. Weren't we supposed to
be metric by 1980?

Jim
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,535
Members
45,008
Latest member
obedient dusk

Latest Threads

Top