Method has too many lines. [28/10] Open
def update
@estimation = Estimation.find(params[:estimation_id]).decorate
@estimation_item = EstimationItem.find(params[:id])
authorize @estimation, :update?
- Read upRead up
- Exclude checks
Checks if the length of a method exceeds some maximum value. Comment lines can optionally be allowed. The maximum allowed length is configurable.
You can set constructs you want to fold with CountAsOne
.
Available are: 'array', 'hash', 'heredoc', and 'method_call'. Each construct
will be counted as one line regardless of its actual size.
NOTE: The ExcludedMethods
and IgnoredMethods
configuration is
deprecated and only kept for backwards compatibility.
Please use AllowedMethods
and AllowedPatterns
instead.
By default, there are no methods to allowed.
Example: CountAsOne: ['array', 'heredoc', 'method_call']
def m
array = [ # +1
1,
2
]
hash = { # +3
key: 'value'
}
<<~HEREDOC # +1
Heredoc
content.
HEREDOC
foo( # +1
1,
2
)
end # 6 points
Method update
has 28 lines of code (exceeds 25 allowed). Consider refactoring. Open
def update
@estimation = Estimation.find(params[:estimation_id]).decorate
@estimation_item = EstimationItem.find(params[:id])
authorize @estimation, :update?
EstimationItemsController#create has approx 6 statements Open
def create
- Read upRead up
- Exclude checks
A method with Too Many Statements
is any method that has a large number of lines.
Too Many Statements
warns about any method that has more than 5 statements. Reek's smell detector for Too Many Statements
counts +1 for every simple statement in a method and +1 for every statement within a control structure (if
, else
, case
, when
, for
, while
, until
, begin
, rescue
) but it doesn't count the control structure itself.
So the following method would score +6 in Reek's statement-counting algorithm:
def parse(arg, argv, &error)
if !(val = arg) and (argv.empty? or /\A-/ =~ (val = argv[0]))
return nil, block, nil # +1
end
opt = (val = parse_arg(val, &error))[1] # +2
val = conv_arg(*val) # +3
if opt and !arg
argv.shift # +4
else
val[0] = nil # +5
end
val # +6
end
(You might argue that the two assignments within the first @if@ should count as statements, and that perhaps the nested assignment should count as +2.)
EstimationItemsController#update has approx 10 statements Open
def update
- Read upRead up
- Exclude checks
A method with Too Many Statements
is any method that has a large number of lines.
Too Many Statements
warns about any method that has more than 5 statements. Reek's smell detector for Too Many Statements
counts +1 for every simple statement in a method and +1 for every statement within a control structure (if
, else
, case
, when
, for
, while
, until
, begin
, rescue
) but it doesn't count the control structure itself.
So the following method would score +6 in Reek's statement-counting algorithm:
def parse(arg, argv, &error)
if !(val = arg) and (argv.empty? or /\A-/ =~ (val = argv[0]))
return nil, block, nil # +1
end
opt = (val = parse_arg(val, &error))[1] # +2
val = conv_arg(*val) # +3
if opt and !arg
argv.shift # +4
else
val[0] = nil # +5
end
val # +6
end
(You might argue that the two assignments within the first @if@ should count as statements, and that perhaps the nested assignment should count as +2.)
EstimationItemsController tests 'request.xhr?' at least 3 times Open
redirect_to estimation_path(@estimation) unless request.xhr?
end
def destroy
@estimation = Estimation.find(params[:estimation_id]).decorate
- Read upRead up
- Exclude checks
Repeated Conditional
is a special case of Simulated Polymorphism
. Basically it means you are checking the same value throughout a single class and take decisions based on this.
Example
Given
class RepeatedConditionals
attr_accessor :switch
def repeat_1
puts "Repeat 1!" if switch
end
def repeat_2
puts "Repeat 2!" if switch
end
def repeat_3
puts "Repeat 3!" if switch
end
end
Reek would emit the following warning:
test.rb -- 4 warnings:
[5, 9, 13]:RepeatedConditionals tests switch at least 3 times (RepeatedConditional)
If you get this warning then you are probably not using the right abstraction or even more probable, missing an additional abstraction.
EstimationItemsController assumes too much for instance variable '@estimation_item' Open
class EstimationItemsController < ApplicationController
- Read upRead up
- Exclude checks
Classes should not assume that instance variables are set or present outside of the current class definition.
Good:
class Foo
def initialize
@bar = :foo
end
def foo?
@bar == :foo
end
end
Good as well:
class Foo
def foo?
bar == :foo
end
def bar
@bar ||= :foo
end
end
Bad:
class Foo
def go_foo!
@bar = :foo
end
def foo?
@bar == :foo
end
end
Example
Running Reek on:
class Dummy
def test
@ivar
end
end
would report:
[1]:InstanceVariableAssumption: Dummy assumes too much for instance variable @ivar
Note that this example would trigger this smell warning as well:
class Parent
def initialize(omg)
@omg = omg
end
end
class Child < Parent
def foo
@omg
end
end
The way to address the smell warning is that you should create an attr_reader
to use @omg
in the subclass and not access @omg
directly like this:
class Parent
attr_reader :omg
def initialize(omg)
@omg = omg
end
end
class Child < Parent
def foo
omg
end
end
Directly accessing instance variables is considered a smell because it breaks encapsulation and makes it harder to reason about code.
If you don't want to expose those methods as public API just make them private like this:
class Parent
def initialize(omg)
@omg = omg
end
private
attr_reader :omg
end
class Child < Parent
def foo
omg
end
end
Current Support in Reek
An instance variable must:
- be set in the constructor
- or be accessed through a method with lazy initialization / memoization.
If not, Instance Variable Assumption will be reported.
EstimationItemsController assumes too much for instance variable '@estimation' Open
class EstimationItemsController < ApplicationController
- Read upRead up
- Exclude checks
Classes should not assume that instance variables are set or present outside of the current class definition.
Good:
class Foo
def initialize
@bar = :foo
end
def foo?
@bar == :foo
end
end
Good as well:
class Foo
def foo?
bar == :foo
end
def bar
@bar ||= :foo
end
end
Bad:
class Foo
def go_foo!
@bar = :foo
end
def foo?
@bar == :foo
end
end
Example
Running Reek on:
class Dummy
def test
@ivar
end
end
would report:
[1]:InstanceVariableAssumption: Dummy assumes too much for instance variable @ivar
Note that this example would trigger this smell warning as well:
class Parent
def initialize(omg)
@omg = omg
end
end
class Child < Parent
def foo
@omg
end
end
The way to address the smell warning is that you should create an attr_reader
to use @omg
in the subclass and not access @omg
directly like this:
class Parent
attr_reader :omg
def initialize(omg)
@omg = omg
end
end
class Child < Parent
def foo
omg
end
end
Directly accessing instance variables is considered a smell because it breaks encapsulation and makes it harder to reason about code.
If you don't want to expose those methods as public API just make them private like this:
class Parent
def initialize(omg)
@omg = omg
end
private
attr_reader :omg
end
class Child < Parent
def foo
omg
end
end
Current Support in Reek
An instance variable must:
- be set in the constructor
- or be accessed through a method with lazy initialization / memoization.
If not, Instance Variable Assumption will be reported.
Assignment Branch Condition size for update is too high. [<4, 31, 2> 31.32/17] Open
def update
@estimation = Estimation.find(params[:estimation_id]).decorate
@estimation_item = EstimationItem.find(params[:id])
authorize @estimation, :update?
- Read upRead up
- Exclude checks
Checks that the ABC size of methods is not higher than the configured maximum. The ABC size is based on assignments, branches (method calls), and conditions. See http://c2.com/cgi/wiki?AbcMetric and https://en.wikipedia.org/wiki/ABC_Software_Metric.
Interpreting ABC size:
-
<= 17
satisfactory -
18..30
unsatisfactory -
>
30 dangerous
You can have repeated "attributes" calls count as a single "branch".
For this purpose, attributes are any method with no argument; no attempt
is meant to distinguish actual attr_reader
from other methods.
Example: CountRepeatedAttributes: false (default is true)
# `model` and `current_user`, referenced 3 times each,
# are each counted as only 1 branch each if
# `CountRepeatedAttributes` is set to 'false'
def search
@posts = model.active.visible_by(current_user)
.search(params[:q])
@posts = model.some_process(@posts, current_user)
@posts = model.another_process(@posts, current_user)
render 'pages/search/page'
end
This cop also takes into account AllowedMethods
(defaults to []
)
And AllowedPatterns
(defaults to []
)
Missing top-level documentation comment for class EstimationItemsController
. Open
class EstimationItemsController < ApplicationController
- Read upRead up
- Exclude checks
Checks for missing top-level documentation of classes and modules. Classes with no body are exempt from the check and so are namespace modules - modules that have nothing in their bodies except classes, other modules, constant definitions or constant visibility declarations.
The documentation requirement is annulled if the class or module has
a #:nodoc:
comment next to it. Likewise, #:nodoc: all
does the
same for all its children.
Example:
# bad
class Person
# ...
end
module Math
end
# good
# Description/Explanation of Person class
class Person
# ...
end
# allowed
# Class without body
class Person
end
# Namespace - A namespace can be a class or a module
# Containing a class
module Namespace
# Description/Explanation of Person class
class Person
# ...
end
end
# Containing constant visibility declaration
module Namespace
class Private
end
private_constant :Private
end
# Containing constant definition
module Namespace
Public = Class.new
end
# Macro calls
module Namespace
extend Foo
end
Example: AllowedConstants: ['ClassMethods']
# good
module A
module ClassMethods
# ...
end
end
Prefer string interpolation to string concatenation. Open
item: "#" + dom_id(@estimation_item),
- Read upRead up
- Exclude checks
Checks for places where string concatenation can be replaced with string interpolation.
The cop can autocorrect simple cases but will skip autocorrecting more complex cases where the resulting code would be harder to read. In those cases, it might be useful to extract statements to local variables or methods which you can then interpolate in a string.
NOTE: When concatenation between two strings is broken over multiple
lines, this cop does not register an offense; instead,
Style/LineEndConcatenation
will pick up the offense if enabled.
Two modes are supported:
1. aggressive
style checks and corrects all occurrences of +
where
either the left or right side of +
is a string literal.
2. conservative
style on the other hand, checks and corrects only if
left side (receiver of +
method call) is a string literal.
This is useful when the receiver is some expression that returns string like Pathname
instead of a string literal.
Safety:
This cop is unsafe in aggressive
mode, as it cannot be guaranteed that
the receiver is actually a string, which can result in a false positive.
Example: Mode: aggressive (default)
# bad
email_with_name = user.name + ' <' + user.email + '>'
Pathname.new('/') + 'test'
# good
email_with_name = "#{user.name} <#{user.email}>"
email_with_name = format('%s <%s>', user.name, user.email)
"#{Pathname.new('/')}test"
# accepted, line-end concatenation
name = 'First' +
'Last'
Example: Mode: conservative
# bad
'Hello' + user.name
# good
"Hello #{user.name}"
user.name + '!!'
Pathname.new('/') + 'test'
Use 2 spaces for indentation in a hash, relative to the start of the line where the left curly brace is. Open
sum: @estimation.sum,
- Read upRead up
- Exclude checks
Checks the indentation of the first key in a hash literal where the opening brace and the first key are on separate lines. The other keys' indentations are handled by the HashAlignment cop.
By default, Hash literals that are arguments in a method call with parentheses, and where the opening curly brace of the hash is on the same line as the opening parenthesis of the method call, shall have their first key indented one step (two spaces) more than the position inside the opening parenthesis.
Other hash literals shall have their first key indented one step more than the start of the line where the opening curly brace is.
This default style is called 'specialinsideparentheses'. Alternative styles are 'consistent' and 'align_braces'. Here are examples:
Example: EnforcedStyle: specialinsideparentheses (default)
# The `special_inside_parentheses` style enforces that the first key
# in a hash literal where the opening brace and the first key are on
# separate lines is indented one step (two spaces) more than the
# position inside the opening parentheses.
# bad
hash = {
key: :value
}
and_in_a_method_call({
no: :difference
})
takes_multi_pairs_hash(x: {
a: 1,
b: 2
},
y: {
c: 1,
d: 2
})
# good
special_inside_parentheses
hash = {
key: :value
}
but_in_a_method_call({
its_like: :this
})
takes_multi_pairs_hash(x: {
a: 1,
b: 2
},
y: {
c: 1,
d: 2
})
Example: EnforcedStyle: consistent
# The `consistent` style enforces that the first key in a hash
# literal where the opening brace and the first key are on
# separate lines is indented the same as a hash literal which is not
# defined inside a method call.
# bad
hash = {
key: :value
}
but_in_a_method_call({
its_like: :this
})
# good
hash = {
key: :value
}
and_in_a_method_call({
no: :difference
})
Example: EnforcedStyle: align_braces
# The `align_brackets` style enforces that the opening and closing
# braces are indented to the same position.
# bad
and_now_for_something = {
completely: :different
}
takes_multi_pairs_hash(x: {
a: 1,
b: 2
},
y: {
c: 1,
d: 2
})
# good
and_now_for_something = {
completely: :different
}
takes_multi_pairs_hash(x: {
a: 1,
b: 2
},
y: {
c: 1,
d: 2
})
Avoid comma after the last item of a hash. Open
},
- Read upRead up
- Exclude checks
Checks for trailing comma in hash literals. The configuration options are:
-
consistent_comma
: Requires a comma after the last item of all non-empty, multiline hash literals. -
comma
: Requires a comma after the last item in a hash, but only when each item is on its own line. -
no_comma
: Does not require a comma after the last item in a hash
Example: EnforcedStyleForMultiline: consistent_comma
# bad
a = { foo: 1, bar: 2, }
# good
a = { foo: 1, bar: 2 }
# good
a = {
foo: 1, bar: 2,
qux: 3,
}
# good
a = {
foo: 1, bar: 2, qux: 3,
}
# good
a = {
foo: 1,
bar: 2,
}
Example: EnforcedStyleForMultiline: comma
# bad
a = { foo: 1, bar: 2, }
# good
a = { foo: 1, bar: 2 }
# bad
a = {
foo: 1, bar: 2,
qux: 3,
}
# good
a = {
foo: 1, bar: 2,
qux: 3
}
# bad
a = {
foo: 1, bar: 2, qux: 3,
}
# good
a = {
foo: 1, bar: 2, qux: 3
}
# good
a = {
foo: 1,
bar: 2,
}
Example: EnforcedStyleForMultiline: no_comma (default)
# bad
a = { foo: 1, bar: 2, }
# good
a = {
foo: 1,
bar: 2
}
Avoid comma after the last item of a hash. Open
total: @estimation_item.total,
- Read upRead up
- Exclude checks
Checks for trailing comma in hash literals. The configuration options are:
-
consistent_comma
: Requires a comma after the last item of all non-empty, multiline hash literals. -
comma
: Requires a comma after the last item in a hash, but only when each item is on its own line. -
no_comma
: Does not require a comma after the last item in a hash
Example: EnforcedStyleForMultiline: consistent_comma
# bad
a = { foo: 1, bar: 2, }
# good
a = { foo: 1, bar: 2 }
# good
a = {
foo: 1, bar: 2,
qux: 3,
}
# good
a = {
foo: 1, bar: 2, qux: 3,
}
# good
a = {
foo: 1,
bar: 2,
}
Example: EnforcedStyleForMultiline: comma
# bad
a = { foo: 1, bar: 2, }
# good
a = { foo: 1, bar: 2 }
# bad
a = {
foo: 1, bar: 2,
qux: 3,
}
# good
a = {
foo: 1, bar: 2,
qux: 3
}
# bad
a = {
foo: 1, bar: 2, qux: 3,
}
# good
a = {
foo: 1, bar: 2, qux: 3
}
# good
a = {
foo: 1,
bar: 2,
}
Example: EnforcedStyleForMultiline: no_comma (default)
# bad
a = { foo: 1, bar: 2, }
# good
a = {
foo: 1,
bar: 2
}
Align the keys of a hash literal if they span more than one line. Open
msg: @estimation_item.errors.full_messages.first,
- Read upRead up
- Exclude checks
Check that the keys, separators, and values of a multi-line hash literal are aligned according to configuration. The configuration options are:
- key (left align keys, one space before hash rockets and values)
- separator (align hash rockets and colons, right align keys)
- table (left align keys, hash rockets, and values)
The treatment of hashes passed as the last argument to a method call can also be configured. The options are:
- always_inspect
- always_ignore
- ignore_implicit (without curly braces)
Alternatively you can specify multiple allowed styles. That's done by passing a list of styles to EnforcedStyles.
Example: EnforcedHashRocketStyle: key (default)
# bad
{
:foo => bar,
:ba => baz
}
{
:foo => bar,
:ba => baz
}
# good
{
:foo => bar,
:ba => baz
}
Example: EnforcedHashRocketStyle: separator
# bad
{
:foo => bar,
:ba => baz
}
{
:foo => bar,
:ba => baz
}
# good
{
:foo => bar,
:ba => baz
}
Example: EnforcedHashRocketStyle: table
# bad
{
:foo => bar,
:ba => baz
}
# good
{
:foo => bar,
:ba => baz
}
Example: EnforcedColonStyle: key (default)
# bad
{
foo: bar,
ba: baz
}
{
foo: bar,
ba: baz
}
# good
{
foo: bar,
ba: baz
}
Example: EnforcedColonStyle: separator
# bad
{
foo: bar,
ba: baz
}
# good
{
foo: bar,
ba: baz
}
Example: EnforcedColonStyle: table
# bad
{
foo: bar,
ba: baz
}
# good
{
foo: bar,
ba: baz
}
Example: EnforcedLastArgumentHashStyle: always_inspect (default)
# Inspect both implicit and explicit hashes.
# bad
do_something(foo: 1,
bar: 2)
# bad
do_something({foo: 1,
bar: 2})
# good
do_something(foo: 1,
bar: 2)
# good
do_something(
foo: 1,
bar: 2
)
# good
do_something({foo: 1,
bar: 2})
# good
do_something({
foo: 1,
bar: 2
})
Example: EnforcedLastArgumentHashStyle: always_ignore
# Ignore both implicit and explicit hashes.
# good
do_something(foo: 1,
bar: 2)
# good
do_something({foo: 1,
bar: 2})
Example: EnforcedLastArgumentHashStyle: ignore_implicit
# Ignore only implicit hashes.
# bad
do_something({foo: 1,
bar: 2})
# good
do_something(foo: 1,
bar: 2)
Example: EnforcedLastArgumentHashStyle: ignore_explicit
# Ignore only explicit hashes.
# bad
do_something(foo: 1,
bar: 2)
# good
do_something({foo: 1,
bar: 2})
Align the keys of a hash literal if they span more than one line. Open
additionalValues: {
sum: @estimation.sum,
buffer: @estimation.buffer,
total: @estimation.total,
actual_sum: @estimation.actual_sum,
- Read upRead up
- Exclude checks
Check that the keys, separators, and values of a multi-line hash literal are aligned according to configuration. The configuration options are:
- key (left align keys, one space before hash rockets and values)
- separator (align hash rockets and colons, right align keys)
- table (left align keys, hash rockets, and values)
The treatment of hashes passed as the last argument to a method call can also be configured. The options are:
- always_inspect
- always_ignore
- ignore_implicit (without curly braces)
Alternatively you can specify multiple allowed styles. That's done by passing a list of styles to EnforcedStyles.
Example: EnforcedHashRocketStyle: key (default)
# bad
{
:foo => bar,
:ba => baz
}
{
:foo => bar,
:ba => baz
}
# good
{
:foo => bar,
:ba => baz
}
Example: EnforcedHashRocketStyle: separator
# bad
{
:foo => bar,
:ba => baz
}
{
:foo => bar,
:ba => baz
}
# good
{
:foo => bar,
:ba => baz
}
Example: EnforcedHashRocketStyle: table
# bad
{
:foo => bar,
:ba => baz
}
# good
{
:foo => bar,
:ba => baz
}
Example: EnforcedColonStyle: key (default)
# bad
{
foo: bar,
ba: baz
}
{
foo: bar,
ba: baz
}
# good
{
foo: bar,
ba: baz
}
Example: EnforcedColonStyle: separator
# bad
{
foo: bar,
ba: baz
}
# good
{
foo: bar,
ba: baz
}
Example: EnforcedColonStyle: table
# bad
{
foo: bar,
ba: baz
}
# good
{
foo: bar,
ba: baz
}
Example: EnforcedLastArgumentHashStyle: always_inspect (default)
# Inspect both implicit and explicit hashes.
# bad
do_something(foo: 1,
bar: 2)
# bad
do_something({foo: 1,
bar: 2})
# good
do_something(foo: 1,
bar: 2)
# good
do_something(
foo: 1,
bar: 2
)
# good
do_something({foo: 1,
bar: 2})
# good
do_something({
foo: 1,
bar: 2
})
Example: EnforcedLastArgumentHashStyle: always_ignore
# Ignore both implicit and explicit hashes.
# good
do_something(foo: 1,
bar: 2)
# good
do_something({foo: 1,
bar: 2})
Example: EnforcedLastArgumentHashStyle: ignore_implicit
# Ignore only implicit hashes.
# bad
do_something({foo: 1,
bar: 2})
# good
do_something(foo: 1,
bar: 2)
Example: EnforcedLastArgumentHashStyle: ignore_explicit
# Ignore only explicit hashes.
# bad
do_something(foo: 1,
bar: 2)
# good
do_something({foo: 1,
bar: 2})
Missing frozen string literal comment. Open
# == Schema Information
- Read upRead up
- Exclude checks
Helps you transition from mutable string literals
to frozen string literals.
It will add the # frozen_string_literal: true
magic comment to the top
of files to enable frozen string literals. Frozen string literals may be
default in future Ruby. The comment will be added below a shebang and
encoding comment. The frozen string literal comment is only valid in Ruby 2.3+.
Note that the cop will accept files where the comment exists but is set
to false
instead of true
.
To require a blank line after this comment, please see
Layout/EmptyLineAfterMagicComment
cop.
Safety:
This cop's autocorrection is unsafe since any strings mutations will
change from being accepted to raising FrozenError
, as all strings
will become frozen by default, and will need to be manually refactored.
Example: EnforcedStyle: always (default)
# The `always` style will always add the frozen string literal comment
# to a file, regardless of the Ruby version or if `freeze` or `<<` are
# called on a string literal.
# bad
module Bar
# ...
end
# good
# frozen_string_literal: true
module Bar
# ...
end
# good
# frozen_string_literal: false
module Bar
# ...
end
Example: EnforcedStyle: never
# The `never` will enforce that the frozen string literal comment does
# not exist in a file.
# bad
# frozen_string_literal: true
module Baz
# ...
end
# good
module Baz
# ...
end
Example: EnforcedStyle: always_true
# The `always_true` style enforces that the frozen string literal
# comment is set to `true`. This is a stricter option than `always`
# and forces projects to use frozen string literals.
# bad
# frozen_string_literal: false
module Baz
# ...
end
# bad
module Baz
# ...
end
# good
# frozen_string_literal: true
module Bar
# ...
end
Indent the right brace the same as the start of the line where the left brace is. Open
} }
- Read upRead up
- Exclude checks
Checks the indentation of the first key in a hash literal where the opening brace and the first key are on separate lines. The other keys' indentations are handled by the HashAlignment cop.
By default, Hash literals that are arguments in a method call with parentheses, and where the opening curly brace of the hash is on the same line as the opening parenthesis of the method call, shall have their first key indented one step (two spaces) more than the position inside the opening parenthesis.
Other hash literals shall have their first key indented one step more than the start of the line where the opening curly brace is.
This default style is called 'specialinsideparentheses'. Alternative styles are 'consistent' and 'align_braces'. Here are examples:
Example: EnforcedStyle: specialinsideparentheses (default)
# The `special_inside_parentheses` style enforces that the first key
# in a hash literal where the opening brace and the first key are on
# separate lines is indented one step (two spaces) more than the
# position inside the opening parentheses.
# bad
hash = {
key: :value
}
and_in_a_method_call({
no: :difference
})
takes_multi_pairs_hash(x: {
a: 1,
b: 2
},
y: {
c: 1,
d: 2
})
# good
special_inside_parentheses
hash = {
key: :value
}
but_in_a_method_call({
its_like: :this
})
takes_multi_pairs_hash(x: {
a: 1,
b: 2
},
y: {
c: 1,
d: 2
})
Example: EnforcedStyle: consistent
# The `consistent` style enforces that the first key in a hash
# literal where the opening brace and the first key are on
# separate lines is indented the same as a hash literal which is not
# defined inside a method call.
# bad
hash = {
key: :value
}
but_in_a_method_call({
its_like: :this
})
# good
hash = {
key: :value
}
and_in_a_method_call({
no: :difference
})
Example: EnforcedStyle: align_braces
# The `align_brackets` style enforces that the opening and closing
# braces are indented to the same position.
# bad
and_now_for_something = {
completely: :different
}
takes_multi_pairs_hash(x: {
a: 1,
b: 2
},
y: {
c: 1,
d: 2
})
# good
and_now_for_something = {
completely: :different
}
takes_multi_pairs_hash(x: {
a: 1,
b: 2
},
y: {
c: 1,
d: 2
})
Prefer single-quoted strings when you don't need string interpolation or special symbols. Open
item: "#" + dom_id(@estimation_item),
- Read upRead up
- Exclude checks
Checks if uses of quotes match the configured preference.
Example: EnforcedStyle: single_quotes (default)
# bad
"No special symbols"
"No string interpolation"
"Just text"
# good
'No special symbols'
'No string interpolation'
'Just text'
"Wait! What's #{this}!"
Example: EnforcedStyle: double_quotes
# bad
'Just some text'
'No special chars or interpolation'
# good
"Just some text"
"No special chars or interpolation"
"Every string in #{project} uses double_quotes"