

Github Ruby Styleguide - fox91
https://github.com/styleguide/ruby

======
rauljara
There was one thing with block chaining that I was really hoping they'd hit
on. They didn't. They had:

    
    
      # good
      names.select { |name| name.start_with?("S") }.map { |name| name.upcase }
    

I've noticed that sort of chaining is changing towards:

    
    
      names.select { |name| name.start_with?("S") }
           .map    { |name| name.upcase }
    

Which can be further chained (if need be) like so:

    
    
      names.select { |name| name.start_with?("S") }
           .map    { |name| name.upcase }
           .sort
           .join(', ')
    

Which, imo, is just better than trying to do it all on one line or using
intermediate variables. It's more of a value call when it comes to the
intermediate variables, though. I'd also use

    
    
      .map(&:upcase)
    

instead of

    
    
      .map { |word| word.upcase }
    

But I think it's perfectly understandable if you find the word.upcase more
explicit and readable.

~~~
jordoh
This seems to be a popular style in javascript (particularly when using
jQuery), but it's not actually valid ruby (edit: ruby 1.8.7, that is - see
reply). The first line forms a valid statement, so the dots would need to be
at the _end_ of each line to indicate a line continuation. So it would need to
be:

    
    
      names.select { |name| name.start_with?("S") }.
            map    { |name| name.upcase }.
            sort.
            join(', ')
    

Which is slightly more annoying in that you need to modify two lines to add a
new chained line (the line you are adding and the dot added to the previous
line).

This also creates a mild headache when refactoring, as any change to the
length of the "names" variable would force you to re-align the entire chain.
You could do something like:

    
    
      names.
        select { |name| name.start_with?("S") }.
        map    { |name| name.upcase }.
        sort.
        join(', ')

~~~
rauljara
> but it's not actually valid ruby.

You are correct that it is invalid for 1.8.6. The code runs just fine in 1.9,
though. I take advantage of many things that don't work in 1.8.6, so I'm not
particularly concerned with my method chaining breaking compatibility.

I prefer the more-than-2-spaces indentation because, by the shape of the code,
it is clearer to me that this is a method chain and not a change in control
structure. That is also obvious by actually reading the code, though, so I'm
fine putting that down to personal preference.

~~~
jordoh
Great to know about 1.9 - just looked through the 1.9 changelog and saw it
described as "Newlines allowed before ternary colon operator (:) and method
call dot operator (.)", so it does seem like they are encouraging this
specific formatting style.

I agree that the fully indented code is much easier to visually parse -
whether that outweighs the refactoring cost is certainly going to vary
depending on the team (in addition to personal preference, as you mention).

------
NateDad
I'm not a Ruby programmer, but a couple of these things just look completely
wrong:

# good

def some_method(some_arr)

    
    
      some_arr.size
    

end

Omitting the return statement is a good thing? How do you know if this method
even returns anything? .size could be a method that doesn't return anything,
right, since parens are optional?

#good

do_something if something_else

This, to me, is horrible.

If you're just scanning down the file, you can easily miss the if statement,
and assume the do_something always goes off.

Also, it's incredibly hard to process when I'm mentally executing the code in
my head. Generally if there's a method call on the left, you just do it... but
now we hit this if statement, ok, so mentally undo the method call we just
processed, now check the if statement... now skip back to the do_something and
reapply the method call... and now skip the if statement and continue on in
the code.

...or you could just do if something_else then do_something (if you really
must have single line if statements, which I am also against, but not so much
as the if statement after the method it's controlling access to)

~~~
xentronium
> Omitting the return statement is a good thing? How do you know if this
> method even returns anything?

All methods return something.

> If you're just scanning down the file, you can easily miss the if statement,
> and assume the do_something always goes off.

This is actually one of the arguable points in that styleguide. Some people
share your disapproval for inline if modifiers. Anyway it's not that bad after
getting used to as long as lines aren't too long and predicates aren't too
complex.

~~~
NateDad
> All methods return something.

Ahh, that helps, thanks.

------
kreeger
I can't stress enough how important it is to _not_ use `and` and `or`. As a
former die-hard fan of those operators, it bit me in the ass so hard when
those didn't exactly work the way they were supposed to. I've been using &&
and || now for years and I haven't looked back. /PSA

~~~
Pewpewarrows
I agree. But in all code that I write, regardless of pretty much whatever
language it's written in, I always explicitly add parentheses around what I
want the order of operations to be.

"1 * 3 + 4 / 20 && foo" is unreadable. No one wants to memorize the order of
operations for every language they use and have to figure it out in their
head. Make life easier for the people who have to maintain that line of code
you just wrote.

~~~
oinksoft
For language-specific operators I could understand ... but to me, the
cognitive load of the parentheses is worse than having to think for a moment
about this particular set of operators which have the same precedence in every
language I've used (and the arithmetic operators which I've had to know the
order of since early grade school).

Maybe I'll eat my foot some day, but

    
    
      (a == 1) && (b == 2)
    

or

    
    
      (2 * 3) + 1
    

is nothing but code smell to me.

~~~
Pewpewarrows
There are plenty of things that you can leave out when writing parseable
source code, but don't because it would make the code horribly un-readable.

That is, there's a reason for whitespace around operators, after commas,
extraneous newlines, etc. It makes the code easier to read and maintain. Now
while I'm willing to admit that this whole area is largely aesthetic and
personal, if you submitted a line of code to me that was just this without the
parentheses:

> 2 * 3 + 1

I would reject the code review in a heartbeat. Part of making your code
readable to others and less error-prone during maintenance is adding
extraneous stuff to it that isn't necessary for the code to
parse/compile/interpret.

------
yalue
I agree with almost everything except for using named groups over the $1-$9
variables in regular expression matching. This may be the case if there are
many capture groups in the expression, but I would argue that

    
    
        /(?<meaningful_var>regexp)/ =~ string

is a fair deal more difficult to read than simply

    
    
        /(regexp)/ =~ string

Almost everybody familiar with PCRE will be familiar with the simpler form,
and it's usually the case that the shorter the regular expression, the easier
it is to understand and read.

~~~
viseztrance
The following are equivalent:

    
    
      if /(?<meaningful_var>regexp)/ =~ string
        puts meaningful_var
      end
    
      if /(regexp)/ =~ string
        puts $1
      end
    

This may not look like much, but bare in mind you may be using the current
selection in several places, at which point you'll probably use the following
for readability either way:

    
    
      meaningful_var = $1
    

In any case I think that sometimes the latter is preferable, that's why I'm
not into these kind of black and white conventions. OMG, this line is 85
characters, you suck.

~~~
yalue
It is true that one will probably immediately reassign the $- variables. And
that's definitely true that there are cases when conventions impede good
style. I would probably say, though, that in most cases the latter of your
examples is preferable.

    
    
        if string =~ /First: (.*?) Last: (.*?)\s/
          first_name = $1
          last_name = $2
          # etc...
        end
    

looks far better to me than

    
    
        if string =~ /First: (?<first_name>.*?) Last: (?<last_name>.*?)\s/
          # etc...
        end

------
jhund
I use pretty much the same style for my Ruby work. One thing I do differently
is replacing

    
    
      %w(word1 word2 word3)
    

with

    
    
      %w[word1 word2 word3]
    

both result in

    
    
      ["word1", "word2", "word3"]
    

I prefer the bracket delimiters since they better indicate the array nature
than the parens. In % notation you can choose your own delimiters, so why not
use brackets?

~~~
yxhuvud
Both are fine.

Just don't use linebreaks or weird utf8 characters, please.

EDIT: As delimeters. Feel free to use them inside the strings.

------
dsr12
Now-a-days we have computers which can show more than 80 characters at a time.
"Keep lines fewer than 80 characters", Is this recommendation still valid?

~~~
bryanlarsen
Shorter lines are easier to read. Short lines let you put up several editor
windows side by side even on a cramped laptop. Short lines let you use a
larger font to save your eyes.

There can also be a code win: when forced to deal with short lines, it's often
easier to split a long line of code into two easier to understand lines than
it is to split on an operator.

Sometimes a split line is a lot worse than a long line, which is why the rule
shouldn't be applied religious -- you should only be called on it if you have
many lines over the limit.

IMO, 80 is a little bit tight; I prefer 100. But I wouldn't bike shed it if
there was a standard in place.

------
Karunamon
I'm a little curious why

    
    
        %w(strings go here) 
    

is preferred to

    
    
         [strings, go, here]
    

The first form requires extra work to escape spaces, the second form is a
representation of an array everywhere in Ruby, including in the debugger and
IRB.

~~~
masklinn
> The first form requires extra work to escape spaces

The first form is generally used for symbol-type strings (word lists,
essentially, hence "w"). It is less syntactically noisy, shorter and requires
less waffling around with non-word keys.

That's especially flagrant if you don't ignore half the actual array,

    
    
        %w(foo bar baz)
    

really results in

    
    
        ["foo", "bar", "baz"]
    

(the quotes are rather important, because they're noisy, repetitive and
annoying to type).

It's one of the few things I regularly wish were in more languages.

~~~
Karunamon
Ahh.. I forgot about the quotes. That's what I get for posting immediately
after waking up. Thanks :)

------
onedognight
I do not know of the single language, including the language of math, that
gives equal precedence to their _and_ and _or_ operators. Sadly Ruby does, and
it's a blight on the language. It's like giving equal precedence to + and \ _.
It's a choice, but not one that anyone would expect.

What's worse, Ruby give the "correct" relative precedence to &&/||. I suspect
this inconsistency is the reason the OP cautions against using _and _/_ or*.
It's too bad because I miss the low precedence and/or operators (from perl)
that can be used to avoid parenthesis that &&/|| would require in the presence
of assignment, etc.

~~~
graywh
Ruby's _and_ and _or_ are for flow control like _if_ and _unless_ , not binary
logic operators like (or synonyms for) _& &_ and _||_.

------
danenania
Agree nearly 100%, except I see no problem with omitting parentheses around
arguments in method definitions. I've never had any trouble parsing this and
it's a bit cleaner to my eye.

~~~
OriginalSyn
In team environments you typically sacrifice convenience for maintainability
and while you may not have a problem with optional parenthesis, it invites
ambiguity and a more junior programmer may make a mistake because of it so the
idea is to close off that edge case completely and not have to worry about it.
This is the same reason a lot of shops ban the terniary operator for anything
more than the simplest of variable assignments. It's not saying it's not
useful, it's just that there are cases where if they had just been there in
the first place coding errors could have been avoided.

~~~
danenania
I agree with your general point, but I don't really see how omitting those
parentheses invites ambiguity.

def reply_to_post _text_

end

What could anyone imagine _text_ to be in this context aside from an argument?
I get that using parentheses is more familiar coming from languages with C
syntax, but I see no other rationale. I've never worked with anyone who
stumbled over this. It's always just: 'oh cool, I didn't realize you could
omit parentheses there.'

~~~
xentronium
It just doesn't scan well. It's quite easy to misread this as
reply_to_post_text, for example.

------
pmahoney
Regarding "def self.method" vs. "class << self; def method; end", one very big
advantage of using the "class << self" technique (which Github discourages) is
that it allows grepping for "def method" to find the location of the method
definition.

Perhaps my editor is old and featureless (and Ruby's dynamic nature doesn't
help), but I grep for such things multiple times per day.

------
zxcdw
This makes me want to learn Ruby so bad. :(

------
TommyDANGerous
Love it. Great read.

------
sabat
I like what I've read, but with a couple of cavaets. Ruby is the way it is on
purpose. Discouraging people from using features of the language because the
OP (presumably) does not understand how to use them: that's an anti-pattern.

 _The and and or keywords are banned. It's just not worth it. Always use &&
and || instead._

If you find "and" and "or" not to be "worth it", it tells me that you don't
understand the difference. The "&&" and "||" versions bind more tightly, and
that is not always desirable. Perl has the same set of constructs, and the
Perl monks have been using them correctly for years.

 _As you can see all the classes in a class hierarchy actually share one class
variable._

Well, yeah. That's meant to be a feature of the language, not "nasty
behavior". It's good advice to use class instance variables, sure. But let's
not imply that Ruby is a badly designed language; it's quite well-designed.
This isn't Javascript. :-)

 _edit: formatting_

~~~
bryanlarsen
Ruby is mostly well-designed, but it certainly has its warts. One of them is
that 'or' and 'and' have the same precedence. They don't in Perl. That's one
reason while Perl monks use them, but Ruby rockstars don't.

And please don't try to tell me that the lambda/proc/block mess is "well-
designed".

