rubocop-hq/rubocop

View on GitHub
docs/modules/ROOT/partials/cops_layout_footer.adoc

Summary

Maintainability
Test Coverage

== AllowMultilineFinalElement

`AllowMultilineFinalElement` is a boolean option (`false` by default) that
is available on the following Layout cops:

  * FirstArrayElementLineBreak
  * FirstHashElementLineBreak
  * FirstMethodArgumentLineBreak
  * FirstMethodParameterLineBreak
  * MultilineArrayLineBreaks
  * MultilineHashKeyLineBreaks
  * MultilineMethodArgumentLineBreaks
  * MultilineMethodParameterLineBreaks

Those cops ignore their respective expressions if all or the elements of
the expression are on the same line. If `AllowMultilineFinalElement` is
set to `true`, the cop will also ignore multiline expressions if the last
element starts on the same line, but ends on a different one.

This works well with `Layout/LineLength` to present elements on
individual lines when wrapping, while not affecting expressions
that are already short enough, and only considered multiline
because of their last element.

Each cop can be configured independently allowing for more fine-grained
control over what is considered good ok in the codebase.

=== Examples

Here are some examples of real world expressions that get wrapped
by their respective cops, but that are considered ok when setting
`AllowMultilineFinalElement` to `true` on those same cops.

[source,ruby]
----
# good

# FirstArrayElementLineBreak and MultilineArrayLineBreaks

  # Array of error containing a single error
  errors = [{
    error: "Something went wrong",
    error_code: error_code,
  }]

  # Array of flags, with last flag computed
  flags = [:a, :b, foo(
    bar,
    baz
  )]

# FirstHashElementLineBreak and MultilineHashKeyLineBreaks
  hash = { foo: 1, bar: 2, baz: {
    c: 1,
    d: 2
  }}

# FirstMethodArgumentLineBreak and MultilineMethodArgumentLineBreaks
  single_argument_hash_method_call({
    a: 1,
    b: 2,
    c: 3
  })

  # Call some method, with a long last argument, that is a hash
  write_log(:error,  {
    "job_class" => job.class.name,
    "resource" => resource.id,
    "message" => "Something wrong happened here",
  })

  # Rails before action with long last argument
  before_action :load_something, only: [
    :show,
    :list,
    :some_other_long_action_name,
  ]

  # Rails validation with inline callback
  validate :name, presence: true, on: [:create, :activate], if: -> {
    active? && some_relationship.any?
  }

  # Rails after commit hook, with some Sorbet bindings
  after_commit :geolocate, unless: -> {
    T.bind(self, Address)
    archived? || invalid?
  }

# FirstMethodParameterLineBreak and MultilineMethodParameterLineBreaks

  # Method with a long last parameter default value
  def foo(foo, bar, baz = {
    a: 1,
    b: 2,
    c: 3
  })
    do_something
  end
----