From: Mark Hubbart Date: 2004-05-02T06:47:41+09:00 Subject: Re: Ruby Newbie (ooh, that rhymes!) - When do I use do/end, when {}? On May 1, 2004, at 2:06 PM, Jean-Hugues ROBERT wrote: > At 05:54 02/05/2004 +0900, you wrote: >> 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. 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