Skip to content

Comment on Github Ruby Styleguide

Comments

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.

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(', ')

> 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.

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).

Agreed. I'm no rubyist, but it's not only much more readable, but functionally easier to manage in code. I can easily comment out one or more blocks or methods in the chain in this case if need be, for example. I'm surprised they advocate it on one line, actually.

Startin' to look like Java (with its fluent-interface pattern) :). Keep it up!

thumbs up

AboutSource Built by g1lg1l

Hackerly is an independent reader for Hacker News, built on the public HN API. Not affiliated with Y Combinator.