Ruby convention for chaining calls over multiple lines Ruby convention for chaining calls over multiple lines ruby ruby

Ruby convention for chaining calls over multiple lines


There is actually a section on that in the Ruby style guide:

Adopt a consistent multi-line method chaining style. There are two popular styles in the Ruby community, both of which are considered good - leading . (Option A) and trailing . (Option B).

  • (Option A) When continuing a chained method invocation on another line keep the . on the second line.

    # bad - need to consult first line to understand second lineone.two.three.  four# good - it's immediately clear what's going on the second lineone.two.three  .four
  • (Option B) When continuing a chained method invocation on another line, include the . on the first line to indicate that the expression continues.

    # bad - need to read ahead to the second line to know that the chain continuesone.two.three  .four# good - it's immediately clear that the expression continues beyond the first lineone.two.three.  four

A discussion on the merits of both alternative styles can be found here.


In Ruby 1.9+ it's possible to write like this:

query = reservations_scope  .for_company(current_company)  .joins{property.development}  .group{property.development.id}  .group{property.development.name}  .group{property.number}  .group{created_at}  .group{price}  .group{reservation_path}  .group{company_id}  .group{user_id}

Much more readable, I think.


Here is a complete list of pros and cons of four options. Two of the options have not been mentioned in any other answer.

Pros and cons can be broken into unique ones and shared ones. Shared pros are the inverses of a unique con of another option. Similarly, shared cons are the inverses of a unique pro of another option. There are also some points that are pros for two options and cons for the other two.

To avoid repeating explanations, I describe each option’s shared pros and cons with just a summary of that point. Full details about a shared pro or con are available in the description of their inverse con or pro in another option’s unique section. For the points that are pros of two options and cons of the other two, I arbitrarily chose to put the full explanations in the set that starts with “. at line beginning”.

For a shorter list that leaves the shared pros and cons implicit instead of repeating them, see this old version of this answer.


. at line end

items.get.lazy.  take(10).  force

Pros

Shared with only one other option:
  • Continuing lines can be commented out freely, and comments can be added between lines
  • Pastable into IRB/Pry
  • Supported in Ruby 1.8
Shared with two other options:
  • When you read the initial line, it is clear that the expression continues
  • Plenty of horizontal space for continuing lines
  • Doesn’t require manual alignment of characters into columns
  • Looks fine when viewed in a proportional font
  • Has a minimum of punctuation, reducing typing and visual noise

Cons

Unique:
  • Continuing lines look strange on their own. You must read the preceding line to understand that they are a continuation.
    • Indentation is not a reliable indicator that a line continues from the previous line – it could merely mean the start of a block.
Shared with only one other option:
  • When editing the code, it is harder to comment out or reorder the last line

. at line beginning

items.get.lazy  .take(10)  .force

Pros

Shared with only one other option:
  • When editing the code, it is easier to comment out or change the order of the last line – no need to delete and add . or \.
Shared with two other options:
  • Continuing lines can be understood when seen on their own
  • Plenty of horizontal space for continuing lines
  • Doesn’t require manual alignment of characters into columns
  • Looks fine when viewed in a proportional font
  • Has a minimum of punctuation, reducing typing and visual noise

Cons

Unique:
  • When you read the initial line, it’s not immediately clear that the expression continues
    • If you use this in your codebase, then when you read a line, you must always check the line after to make sure that it doesn’t affect the initial line’s meaning.
Shared with only one other option:
  • The code silently breaks if you # comment out a continuing line, or add a comment between lines
  • You can’t paste this code into IRB/Pry without it being misinterpreted
  • Not supported in Ruby 1.8 and below

. at line beginning, indented to the previous .

items.get.lazy         .take(10)         .force

Pros

Shared with only one other option:
  • When editing the code, it is easier to comment out or change the order of the last line – no need to delete and add . or \.
Shared with two other options:
  • When you read the initial line, it is clear that the expression continues
  • Continuing lines can be understood when seen on their own
  • Has a minimum of punctuation, reducing typing and visual noise

Cons

Unique:
  • Each line’s code must fit into less horizontal space
  • Requires manual alignment of the .s into columns
    • It is easier if you have an editor plugin for aligning text, but still more work than using default indentation rules.
    • Even if your editing setup includes a plugin for alignment, your coworkers’ setups may not.
  • The code will look misaligned when viewed in a proportional font
Shared with only one other option:
  • The code silently breaks if you # comment out a continuing line, or add a comment between lines
  • You can’t paste this code into IRB/Pry without it being misinterpreted
  • Not supported in Ruby 1.8 and below
Shared with two other options:
  • When editing the code, it is harder to comment out or reorder the last line

\ at line end, . at next line’s beginning

items.get.lazy \  .take(10) \  .force

Pros

Shared with only one other option:
  • Continuing lines can be commented out freely, and comments can be added between lines
  • Pastable into IRB/Pry
  • Supported in Ruby 1.8
Shared with two other options:
  • When you read the initial line, it is clear that the expression continues
  • Continuing lines can be understood when seen on their own
  • Plenty of horizontal space for continuing lines
  • Doesn’t require manual alignment of characters into columns
  • Looks fine when viewed in a proportional font

Cons

Unique:
  • Requires more typing
  • Creates more visual noise
Shared with only one other option:
  • When editing the code, it is harder to comment out or reorder the last line