Elements of Ruby Style

Hello all,
I’m happy announce a project that I’ve been working on for a little
while.

I’ve noticed that a lot of posts on the mailing are “what’s the most
rubyish way to do (x)?” where x could be transversing a file and
matching regexes to looping through records in a database to switching
between two logic branches. So, seeing this, I thought, why not give
these people a refernece? Instead of having to type out a long answer
every time, why not give them a Fine Manual to read?

So I began work on Elements of Ruby: a descriptive style manual, that
is, that this manual will only describe the typical style used in the
language, and should not be used as a way to prescribe style. I want
it to be used as a learning tool and to answer questions about the
best style in a given situation rather than to spawn religious
arguments about style.

The problem is that I havent gotten very far yet (darn you holidays
and book deadlines! ;)). Actually, that’s why I’m posting here: I
need your help. I’ve managed to build a small list of items so far
(viewable at http://www.elementsofrubystyle.com/ ), but I want to add
more. So I thought I would open discussion here for input. I want it
to be useful to everyone, so everyone should have some input, yes?

I have a Rails applicatio built to power it, but I want to nail down a
fairly final list of things before I populate its database and deploy
it. After it’s deployed, then you will be able to submit comments on
each element (e.g., to voice an exception or add to it) and submit
examples for each one (that will be integrated and properly
attributed) or suggest new things to be added/changed.

Anyhow, look at the list, and let’s talk about what should be on there.

Visit http://www.elementsofrubystyle.com/ .

–Jeremy


My free Ruby e-book:
http://www.humblelittlerubybook.com/book/

My blogs:

http://www.rubyinpractice.com/

On 1/9/07, Jeremy McAnally [email protected] wrote:

Anyhow, look at the list, and let’s talk about what should be on there.

Visit http://www.elementsofrubystyle.com/ .

I like what you’ve got and for most cases I agree with your style
guidelines. I’ve been programming Ruby for about 1.5 years and have
created several gems for distribution, so I’ve seen many of the issues
you cover.

My comments:

  • A section on commenting code, especially so it is RDoc compatible
    (i.e. place all text in contiguous lines starting with #, or use
    =begin, =end for particularly long comments).

  • When commenting, indicate the type of object returned and the type
    of those accepted. Not in the strong-typing sense, but for
    documentation purposes. Trying to figure out what methods are
    available on objects returned can be a real trial-and-error process if
    it’s not well documented.

  • (Personal style) - Place all “assertion” handling code at the
    beginning of each method. For example:

    def some_method(arg1, arg)
    raise “Arg1 cannot be nil” if arg1.nil?
    raise “Arg1 must be a number” unless arg1.is_a?(Numeric)

I’ve found its a nice way to document what a method considers legal.

  • (Personal Style) - Don’t use a string to define a new method unless
    you need interpolation. You usually only need it when code within the
    method must be different based on some conditional.

  • Finally, I think you should make explicit mention of the DRY
    principle.

A few specific points I don’t agree with or have questions about:

  • 2.h.i - " There is no advantage … " - Single quoted strings do
    not interpolate, while double-quoted do. You seem to be stating there
    is no difference between them.

  • 2.h.iii - “Multi-line strings should be expressed …” - You mention
    that here-docs should not be used if interpolation is needed. I’m not
    sure why, because interpolation works fine in here docs.

  • 2.c.ii - “Curly braces should be used if the return value is
    desired” - Why? This isn’t a style I’ve seen much in the wild. Is it
    used throughout the Rails source?

  • 2.c.iii - “Use parametrized variables rather than accessing scope
    variables” - This seems to say you shouldn’t take advantage of the
    closure property of blocks (i.e. that in-scope references are carried
    around and can be used). If that’s true, why? If not, a clarification
    should be made.

Hope this helps. Looks like you are off to a great start. Is an RSS
feed going to be available soon?

Justin

Jeremy McAnally wrote:

Hello all,
I’m happy announce a project that I’ve been working on for a little while.

I’ve noticed that a lot of posts on the mailing are “what’s the most
rubyish way to do (x)?” where x could be transversing a file and
matching regexes to looping through records in a database to switching
between two logic branches. So, seeing this, I thought, why not give
these people a refernece? Instead of having to type out a long answer
every time, why not give them a Fine Manual to read?

See also

http://wiki.rubygarden.org/Ruby/page/show/RubyStyleGuide
http://wiki.rubygarden.org/Ruby/page/show/RubyIdioms


James B.

“Inside every large system there’s a small system trying to get out”.
- Chet Hendrickson

I think that’s a good idea, but I have some questions about some items:

2.b.vi. If a your method has a block parameter, try to use yield rather
than accepting it as a variable and calling call on it.
–> What is the reasoning behind this? I’m not trying to criticize (yet
;-), but it seems like The Ruby Way is not doing this. For example, $_
= “hollywood”; scan(/o/); isn’t preferred over “hollywood”.scan(/o/).

2.b.viii and 2.b.x seem to be very similar, perhaps merge them?

2.c.ii says “curly braces” while 2.c.i just says “braces.” Also, what
if you want something’s return value but you do it on multiple lines?
Either that never happens, so the rule isn’t necessary, or it happens
and then you have a conflict in the rules.

2.e.i Use try catch to control flow rather than rescue blocks
–> Do you mean catch/throw? I don’t recall a try/catch in Ruby and a
quick Googling finds nothing.

2.f I think a lot of these need some example code (before and after).
What is a statement modifier? &&, !, etc?

2.h.i There is no advantage to using single quotes or double quotes
other than safety
–> Double quotes allow interpolation and have more escape sequences.
What is “safety” in this context?

2.h.ii Don’t combine string literals and variables using +; rather,
use interpolation
–> What if I want to append something to an existing string? Should I
use existingString = “#{existingString}#{newString}” or existingString
<< newString? (Or +=?)

2.h.iii I think a previous email went over this.

3.b.i Should have an example.

3.b.v Is a repeat of 2.g.i, although maybe it is important enough to be
repeated!

<…>

  • 2.h.iii - “Multi-line strings should be expressed …” - You mention
    that here-docs should not be used if interpolation is needed. I’m not
    sure why, because interpolation works fine in here docs.
    <…>

It depends.

puts <<MARKER
… double quoted string rules apply here
MARKER

puts <<“MARKER”
… double quoted string rules apply here
MARKER

puts <<‘MARKER’
… single quoted string rules apply here - no interpolation
MARKER

Regards,
Rimantas

2.b.vi. If a your method has a block parameter, try to use yield rather
than accepting it as a variable and calling call on it.
→ What is the reasoning behind this? I’m not trying to criticize (yet
;-), but it seems like The Ruby Way is not doing this. For example, $_
= “hollywood”; scan(/o/); isn’t preferred over “hollywood”.scan(/o/).

My personal reasoning is that you end up with less confusion as to
what’s going on when simply looking at the code. You know that yield
yeilds, but an object may have a call method. Secondly, when calling
the method, it’s cleaner when calling. You get:

mymethod { puts “Go go gadget method!” }

as opposed to…

mymethod(lambda { puts “Go go gadget lambda!” })

Just personal preference I suppose.

2.c.ii says “curly braces” while 2.c.i just says “braces.” Also, what
if you want something’s return value but you do it on multiple lines?
Either that never happens, so the rule isn’t necessary, or it happens
and then you have a conflict in the rules.

True, I’ll fix that.

2.e.i Use try catch to control flow rather than rescue blocks
→ Do you mean catch/throw? I don’t recall a try/catch in Ruby and a
quick Googling finds nothing.

You’re right; that’s C# on the brain (and shows how often I use
catch/throw ;)).

2.f I think a lot of these need some example code (before and after).
What is a statement modifier? &&, !, etc?

No, a statement modifier is like this:

puts “Do only if I’m true!” if me == true

Examples will be provided to clear up any confusion.

2.h.i There is no advantage to using single quotes or double quotes
other than safety
→ Double quotes allow interpolation and have more escape sequences.
What is “safety” in this context?

“Advantage” should say “speed advantage”; in other languages (i.e.,
PHP) there is a different in how these things are handled, thus
affecting speed during certain operations.

I’m not sure why I put safety there; probably something to do with
escape sequences. Ill have to look back at my more annotated version
and clear that up.

2.h.ii Don’t combine string literals and variables using +; rather,
use interpolation
→ What if I want to append something to an existing string? Should I
use existingString = “#{existingString}#{newString}” or existingString
<< newString? (Or +=?)

Probably, yes, any of those. I’m mostly referring to not doing
something like this:

mystring = "This is what " + your_name + " is looking for in " +
that_place

That’s how I did strings when I first came to Ruby, but it’s not very
pretty; it’s just my PHP roots showing. Plus, using interpolation
gives you an automatic to_s.

Thanks for the feedback all! I’m working on some revisions and such
right now, but keep it coming. :slight_smile:

–Jeremy


My free Ruby e-book:
http://www.humblelittlerubybook.com/book/

My blogs:

http://www.rubyinpractice.com/

Hi –

On Wed, 10 Jan 2007, Jeremy McAnally wrote:

mymethod { puts “Go go gadget method!” }

as opposed to…

mymethod(lambda { puts “Go go gadget lambda!” })

It sounds like you guys are talking about two different things. (I’m
not sure how Daniel’s example relates to the yield/call matter.)
Also, Jeremy, I thought what you were talking about was this:

def meth
yield
end

vs.

def meth(&block)
block.call
end

In neither case do you need to create a lambda explicitly; the method
calling syntax would be exactly the same:

meth { puts “whatever” }

David

[email protected] wrote:

I’m not sure how Daniel’s example relates to the yield/call matter.

It’s kind of a null issue now, IMO, now that the method of passing
blocks is cleared up, but this is what I meant:

$_ = “hello”
scan(/l/)
This example has a receiver that is not explicit (not in the sense that
the receiver is self but that it is not on that line). This method is
falling out of favor for the above reason.

def meth
yield
end
This example also has a yield with no explicit receiver as defined
above. If the above example is going out of favor, why is this one the
preferred method?

end

This is what I was referring to as well, if it isn’t obvious from my
other replies I’m sorry.

David
Dan

Hi –

On Wed, 10 Jan 2007, Daniel F. wrote:

out of favor for the above reason.

def meth
yield
end
This example also has a yield with no explicit receiver as defined above. If
the above example is going out of favor, why is this one the preferred
method?

yield is a keyword, though, not a method, so they’re not exactly
commensurate. But in any case, it’s not that receiverless method
calls are out of favor, but more the implicit use of $_ as a receiver.
It’s actually something I’ve seen so little of, and so little
discussion of, that I’m not sure what people’s current thinking is on
it. But it’s not connected to yield, which doesn’t have a receiver at
all, nor to the general practice of leaving off receivers where
possible.

David

It’s the same calling semantics. The advantage when writing code is
really just that code which uses yield is faster and looks better than
code that explicitly calls the block.

Ack! You guys are right. Senior moment (actually, it was a I stayed
up til 3:30am writing and then worked all day moment…but same effect
;)). That was one that I had picked up from another page or ML post;
I’m sure I had reasons but now that I look at it it doesn’t make
sense. My mistake!

looks a lot better than

“#{a}#{b}”

Right, that’s why I said literals. When I combine two string objects,
I usually use + just because semantically it makes more sense, but
when there’s a string literal involved, I usually use interpolation.
I think this is a preference thing, but I always thought that was
general practice. Please do correct me if I’m wrong.

–Jeremy


My free Ruby e-book:
http://www.humblelittlerubybook.com/book/

My blogs:

http://www.rubyinpractice.com/

Maybe some example… would be nice :wink:

“Justin B.” [email protected] writes:

def some_method(arg1, arg)
raise “Arg1 cannot be nil” if arg1.nil?
raise “Arg1 must be a number” unless arg1.is_a?(Numeric)

This seems to be a style thing I only see in my own code, but which I
consider very helpful when reading code: put two spaces before
statement modifiers.

I’d have written:

def some_method(arg1, arg)
raise “Arg1 cannot be nil” if arg1.nil?
raise “Arg1 must be a number” unless arg1.is_a?(Numeric)

(In this case, I’d probably line them up, too…)

Since this is the only place I use two spaces in source code, it
slightly stands out and visually seperates the statement from the
modifier, which is especially important if you don’t use syntax
highlighting.

Any comments?

On Wed, 10 Jan 2007, Jeremy McAnally wrote:

mymethod { puts “Go go gadget method!” }

as opposed to…

mymethod(lambda { puts “Go go gadget lambda!” })

Just personal preference I suppose.

This isn’t making sense to me. “hollywood”.scan(/o/) doesn’t have
anything to do with using yield rather than explicitly call()ing a block
via a variable.

And what you say, to yield rather than accepting a block param
explicitly
and then using call() on it, it true, but that really doesn’t affect the
semantics of the calling API, as you show in your example.

class Foo
def a
yield
end

def b(&blk)
blk.call
end
end

z = Foo.new
z.a {7}
z.b {7}

It’s the same calling semantics. The advantage when writing code is
really just that code which uses yield is faster and looks better than
code that explicitly calls the block.

That’s how I did strings when I first came to Ruby, but it’s not very
pretty; it’s just my PHP roots showing. Plus, using interpolation
gives you an automatic to_s.

I think it’s a good idea to discuss the reasons, here.

Sometimes, + is what you want. When dealing with strings, + will give
you
a new String. If you just want to combine two things, though, << is
often
your best bet because it simply modifies the string it is called on
instead of creating a new String, and

a << b

looks a lot better than

“#{a}#{b}”

Kirk H.

Hi –

On Thu, 11 Jan 2007, Christian N. wrote:

slightly stands out and visually seperates the statement from the
modifier, which is especially important if you don’t use syntax
highlighting.

Any comments?

I have a bit of a preference for not doing that. It detaches the
modifier from the modifiee (?), with a slight tendency to make it look
like a new statement is starting.

But lining up might counteract that effect.

David