I have a coworker who is actively trying to convince me that I should not use do..end and instead use curly braces for defining multiline blocks in Ruby.
I'm firmly in the camp of only using curly braces for short one-liners and do..end for everything else. But I thought I would reach out to the greater community to get some resolution.
So which is it, and why? (Example of some shoulda code)
context do
setup { do_some_setup() }
should "do somthing" do
# some more code...
end
end
or
context {
setup { do_some_setup() }
should("do somthing") {
# some more code...
}
}
Personally, just looking at the above answers the question for me, but I wanted to open this up to the greater community.
There is a subtle difference between them, but { } binds tighter than do/end.
The general convention is to use do..end for multi-line blocks and curly braces for single line blocks, but there is also a difference between the two that can be illustrated with this example:
This means that {} has a higher precedence than do..end, so keep that in mind when deciding what you want to use.
P.S: One more example to keep in mind while you develop your preferences.
The following code:
really means:
And this code:
really means:
So to get the actual definition that you want, with curly braces, you must do:
Maybe using braces for parameters is something you want to do anyways, but if you don't it's probably best to use do..end in these cases to avoid this confusion.
There's a third option: Write a preprocessor to infer "end" on its own line, from indentation. The deep thinkers who prefer concise code happen to be right.
Better yet, hack ruby so this is a flag.
Of course, the "pick your fights" simplest solution is to adopt the style convention that a sequence of ends all appear on the same line, and teach your syntax coloring to mute them. For ease of editing, one could use editor scripts to expand/collapse these sequences.
20% to 25% of my ruby code lines are "end" on their own line, all trivially inferred by my indentation conventions. Ruby is the lisp-like language to have achieved the greatest success. When people dispute this, asking where are all the ghastly parentheses, I show them a ruby function ending in seven lines of superfluous "end".
I did code for years using a lisp preprocessor to infer most parentheses: A bar '|' opened a group that autoclosed at the end of the line, and a dollar sign '$' served as an empty placeholder where there would otherwise be no symbols to help infer the groupings. This is of course religious war territory. Lisp/scheme without the parentheses is the most poetic of all languages. Still, it is easier to simply quiet down parentheses using syntax coloring.
I still code with a preprocessor for Haskell, to add heredocs, and to default all flush lines as comments, everything indented as code. I dislike comment characters, whatever the language.
I put another Answer, although the big difference was already pointed out (prcedence/binding), and that can cause hard to find problems (the Tin Man, and others pointed that out). I think my example shows the problem with a not so usual code snippet, even experienced programmeres do not read like the sunday times:
Then i did some code beautifying ...
if you change the
{}
here todo/end
you will get the error, that methodtranslate
does not exist ...Why this happens is pointed out here more than one - precedence. But where to put braces here? (@the Tin Man: I always use braces, like you, but here ... overseen)
so every answer like
is just wrong if used without the "BUT Keep an eye on braces / precedence!"
again:
and
(what ever the result of extend does with the block ...)
So if you want to use do/end use this:
There is one major benefit to curly braces - many editors have a MUCH easier time of matching them, making certain types of debugging much easier. Meanwhile, the keyword "do...end" is quite a bit harder to match, especially since "end"s also match "if"s.
Actually it's a personal preference, but having said that, for past 3 years of my ruby experiences what I have learnt is that ruby has its style.
One example would be, if you are comming from a JAVA background , for a boolean method you might use
notice the camel case and most often 'is' prefix to identify it as a boolean method.
But in ruby world, the same method would be
so I personally think, it's better to go with 'ruby way' (But I know it takes some time for one to understand (it took me around 1 year :D)).
Finally, I would go with
blocks.