Missing magic comment # frozen_string_literal: true
. Open
module Periods
- Read upRead up
- Exclude checks
This cop is designed to help upgrade to after Ruby 3.0. It will add the
comment # frozen_string_literal: true
to the top of files to
enable frozen string literals. Frozen string literals may be default
after Ruby 3.0. The comment will be added below a shebang and encoding
comment. The frozen string literal comment is only valid in Ruby 2.3+.
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
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
Memoized variable @year_value
does not match method name to_year
. Use @to_year
instead. Open
@year_value ||= Year.new(@year.to_s)
- Read upRead up
- Exclude checks
This cop checks for memoized methods whose instance variable name does not match the method name.
This cop can be configured with the EnforcedStyleForLeadingUnderscores directive. It can be configured to allow for memoized instance variables prefixed with an underscore. Prefixing ivars with an underscore is a convention that is used to implicitly indicate that an ivar should not be set or referencd outside of the memoization method.
Example: EnforcedStyleForLeadingUnderscores: disallowed (default)
# bad
# Method foo is memoized using an instance variable that is
# not `@foo`. This can cause confusion and bugs.
def foo
@something ||= calculate_expensive_thing
end
# good
def _foo
@foo ||= calculate_expensive_thing
end
# good
def foo
@foo ||= calculate_expensive_thing
end
# good
def foo
@foo ||= begin
calculate_expensive_thing
end
end
# good
def foo
helper_variable = something_we_need_to_calculate_foo
@foo ||= calculate_expensive_thing(helper_variable)
end
Example: EnforcedStyleForLeadingUnderscores: required
# bad
def foo
@something ||= calculate_expensive_thing
end
# bad
def foo
@foo ||= calculate_expensive_thing
end
# good
def foo
@_foo ||= calculate_expensive_thing
end
# good
def _foo
@_foo ||= calculate_expensive_thing
end
Example: EnforcedStyleForLeadingUnderscores :optional
# bad
def foo
@something ||= calculate_expensive_thing
end
# good
def foo
@foo ||= calculate_expensive_thing
end
# good
def foo
@_foo ||= calculate_expensive_thing
end
# good
def _foo
@_foo ||= calculate_expensive_thing
end
Memoized variable @dhis2
does not match method name to_dhis2
. Use @to_dhis2
instead. Open
@dhis2 ||= "#{@year}#{@month.to_s.rjust(2, '0')}"
- Read upRead up
- Exclude checks
This cop checks for memoized methods whose instance variable name does not match the method name.
This cop can be configured with the EnforcedStyleForLeadingUnderscores directive. It can be configured to allow for memoized instance variables prefixed with an underscore. Prefixing ivars with an underscore is a convention that is used to implicitly indicate that an ivar should not be set or referencd outside of the memoization method.
Example: EnforcedStyleForLeadingUnderscores: disallowed (default)
# bad
# Method foo is memoized using an instance variable that is
# not `@foo`. This can cause confusion and bugs.
def foo
@something ||= calculate_expensive_thing
end
# good
def _foo
@foo ||= calculate_expensive_thing
end
# good
def foo
@foo ||= calculate_expensive_thing
end
# good
def foo
@foo ||= begin
calculate_expensive_thing
end
end
# good
def foo
helper_variable = something_we_need_to_calculate_foo
@foo ||= calculate_expensive_thing(helper_variable)
end
Example: EnforcedStyleForLeadingUnderscores: required
# bad
def foo
@something ||= calculate_expensive_thing
end
# bad
def foo
@foo ||= calculate_expensive_thing
end
# good
def foo
@_foo ||= calculate_expensive_thing
end
# good
def _foo
@_foo ||= calculate_expensive_thing
end
Example: EnforcedStyleForLeadingUnderscores :optional
# bad
def foo
@something ||= calculate_expensive_thing
end
# good
def foo
@foo ||= calculate_expensive_thing
end
# good
def foo
@_foo ||= calculate_expensive_thing
end
# good
def _foo
@_foo ||= calculate_expensive_thing
end
Memoized variable @quarter
does not match method name to_quarter
. Use @to_quarter
instead. Open
@quarter ||= YearQuarter.from_year_month(year, month)
- Read upRead up
- Exclude checks
This cop checks for memoized methods whose instance variable name does not match the method name.
This cop can be configured with the EnforcedStyleForLeadingUnderscores directive. It can be configured to allow for memoized instance variables prefixed with an underscore. Prefixing ivars with an underscore is a convention that is used to implicitly indicate that an ivar should not be set or referencd outside of the memoization method.
Example: EnforcedStyleForLeadingUnderscores: disallowed (default)
# bad
# Method foo is memoized using an instance variable that is
# not `@foo`. This can cause confusion and bugs.
def foo
@something ||= calculate_expensive_thing
end
# good
def _foo
@foo ||= calculate_expensive_thing
end
# good
def foo
@foo ||= calculate_expensive_thing
end
# good
def foo
@foo ||= begin
calculate_expensive_thing
end
end
# good
def foo
helper_variable = something_we_need_to_calculate_foo
@foo ||= calculate_expensive_thing(helper_variable)
end
Example: EnforcedStyleForLeadingUnderscores: required
# bad
def foo
@something ||= calculate_expensive_thing
end
# bad
def foo
@foo ||= calculate_expensive_thing
end
# good
def foo
@_foo ||= calculate_expensive_thing
end
# good
def _foo
@_foo ||= calculate_expensive_thing
end
Example: EnforcedStyleForLeadingUnderscores :optional
# bad
def foo
@something ||= calculate_expensive_thing
end
# good
def foo
@foo ||= calculate_expensive_thing
end
# good
def foo
@_foo ||= calculate_expensive_thing
end
# good
def _foo
@_foo ||= calculate_expensive_thing
end
Use safe navigation (&.
) instead of checking if an object exists before calling the method. Open
month = month[1..-1] if month && month.is_a?(String) && month.start_with?("0")
- Read upRead up
- Exclude checks
This cop transforms usages of a method call safeguarded by a non nil
check for the variable whose method is being called to
safe navigation (&.
). If there is a method chain, all of the methods
in the chain need to be checked for safety, and all of the methods will
need to be changed to use safe navigation. We have limited the cop to
not register an offense for method chains that exceed 2 methods.
Configuration option: ConvertCodeThatCanStartToReturnNil
The default for this is false
. When configured to true
, this will
check for code in the format !foo.nil? && foo.bar
. As it is written,
the return of this code is limited to false
and whatever the return
of the method is. If this is converted to safe navigation,
foo&.bar
can start returning nil
as well as what the method
returns.
Example:
# bad
foo.bar if foo
foo.bar.baz if foo
foo.bar(param1, param2) if foo
foo.bar { |e| e.something } if foo
foo.bar(param) { |e| e.something } if foo
foo.bar if !foo.nil?
foo.bar unless !foo
foo.bar unless foo.nil?
foo && foo.bar
foo && foo.bar.baz
foo && foo.bar(param1, param2)
foo && foo.bar { |e| e.something }
foo && foo.bar(param) { |e| e.something }
# good
foo&.bar
foo&.bar&.baz
foo&.bar(param1, param2)
foo&.bar { |e| e.something }
foo&.bar(param) { |e| e.something }
foo && foo.bar.baz.qux # method chain with more than 2 methods
foo && foo.nil? # method that `nil` responds to
# Method calls that do not use `.`
foo && foo < bar
foo < bar if foo
# This could start returning `nil` as well as the return of the method
foo.nil? || foo.bar
!foo || foo.bar
# Methods that are used on assignment, arithmetic operation or
# comparison should not be converted to use safe navigation
foo.baz = bar if foo
foo.baz + bar if foo
foo.bar > 2 if foo