The Artima Developer Community
Sponsored Link

Ruby Buzz Forum
Ruby Blocks, do or brace?

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Rick DeNatale

Posts: 269
Nickname: rdenatale
Registered: Sep, 2007

Rick DeNatale is a consultant with over three decades of experience in OO technology.
Ruby Blocks, do or brace? Posted: Oct 2, 2007 9:58 AM
Reply to this message Reply

This post originated from an RSS feed registered with Ruby Buzz by Rick DeNatale.
Original Post: Ruby Blocks, do or brace?
Feed Title: Talk Like A Duck
Feed URL: http://talklikeaduck.denhaven2.com/articles.atom
Feed Description: Musings on Ruby, Rails, and other topics by an experienced object technologist.
Latest Ruby Buzz Posts
Latest Ruby Buzz Posts by Rick DeNatale
Latest Posts From Talk Like A Duck

Advertisement
Red Block by Uwe Hermann CC-by-SA Conventional wisdom in Ruby is to use do/end to delimit blocks which contain more than one line of code, and braces for one-line blocks. I've always tended to loosely follow this advice.

Thanks to ruby-talk, I just became aware of Jim Weirich's suggestion to use braces for blocks when the value is being used, and do/end for blocks which are primarily sequences of statements. Jim actually posted this over three years ago, and Joe O'Brien brought it up more recently.

On the whole, I like this idea and will probably adopt it to tune my use of do/end vs. braces.

But don't all blocks return a value?

Here's Jim's prescription:

  • Use { } for blocks that return values
  • Use do / end for blocks that are executed for side effects

For the pedantic minded, it's true that all Ruby blocks actually return values. Every Ruby statement and expression, returns a value. Some folks have used this to object to the suggestion, or at least question it.

At the risk of putting words in Jim's mouth, I believe that he's really talking here about the use/non-use of the value of the block. If you use the value of the block then tilt more to using braces. If the value is discarded then lean towards do/end.

Why I Like this idea

Visually {x + 7} feels more like ( x + 7) than do; x + 7; end does.

Related Things

I've always been slightly uncomfortable writing code like this:

collection.select do | x |
  something
  something_else
end.some_other_method

Instead I think that:

collection.select { | x |
	something
	something_else
}.some_other_method

Just looks better to my eye, despite the multi-line block body.

When I first started writing this, I was thinking that this was an example of Jim's style, but it really isn't. First of all the value of the block is being used, but not directly in the code we're looking at. It's being used internally by the select method.

Now I don't think that you should use braces for any block passed to a method like select, even though the value is being used there.

Second, the value we're using here isn't the value of the block but the value of the select method call.

That said, I still like using the braces in this case.

Another tension

Keep in mind that you aren't completely free to substitute braces for do/end. Sometimes you need to bow to Ruby's precedence rules. Generally in Ruby if something has both a word and a symbolic representation, e.g. {} vs do/end, || vs or, etc. The symbolic version has higher syntactic precedence than the word version. This comes up at times, particularly when you are using a DSL in it's 'natural' mode and not using 'unnecessary' parentheses. For example in Rake:

description 'pickup up the leaves'
task :rake => pre_raking_tasks do
  #code to rake the leaves
end

Works as expected, but:

description 'pickup up the leaves'
task :rake => pre_raking_tasks {#code to rake the leaves}

Won't because it actually means

description 'pickup up the leaves'
task :rake => (pre_raking_tasks {#code to rake the leaves})

The block is given to the pre_raking_tasks invocation rather than the task invocation. So you either need to use do/end or parenthesize explicitly:

description 'pickup up the leaves'
task(:rake => pre_raking_tasks) {#code to rake the leaves})

Read: Ruby Blocks, do or brace?

Topic: Are Screencasts the Future? Previous Topic   Next Topic Topic: What's New in Edge Rails: Your DB Adapter May Have Left the Building

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use