class RuboCop::Cop::Style::MutableConstant
end.freeze
end
puts 1
def foo
CONST = Struct.new do
# good
CONST = Something.new.freeze
# good
end
end
puts 1
def foo
CONST = Struct.new do
# bad
CONST = Something.new
# bad
@example EnforcedStyle: strict
CONST = Something.new
# good
TESTING
This is a heredoc
CONST = <<~TESTING.freeze
# good
CONST = [1, 2, 3].freeze
# good
CONST = [1, 2, 3]
# bad
@example EnforcedStyle: literals (default)
frozen object.
positives. Luckily, there is no harm in freezing an already
frozen objects so there is a decent chance of getting some false
updated with an exhaustive list of all methods that will produce
Strict mode is considered an experimental feature. It has not been
just literals.
Strict mode can be used to freeze all constants, rather than
mutable literal (e.g. array or hash).
This cop checks whether some constant value isn’t a
def autocorrect(node)
def autocorrect(node) expr = node.source_range lambda do |corrector| splat_value = splat_value(node) if splat_value correct_splat_expansion(corrector, expr, splat_value) elsif node.array_type? && !node.bracketed? corrector.insert_before(expr, '[') corrector.insert_after(expr, ']') elsif requires_parentheses?(node) corrector.insert_before(expr, '(') corrector.insert_after(expr, ')') end corrector.insert_after(expr, '.freeze') end end
def check(value)
def check(value) range_enclosed_in_parentheses = range_enclosed_in_parentheses?(value) return unless mutable_literal?(value) || range_enclosed_in_parentheses return if FROZEN_STRING_LITERAL_TYPES.include?(value.type) && frozen_string_literals_enabled? add_offense(value) end
def correct_splat_expansion(corrector, expr, splat_value)
def correct_splat_expansion(corrector, expr, splat_value) if range_enclosed_in_parentheses?(splat_value) corrector.replace(expr, "#{splat_value.source}.to_a") else corrector.replace(expr, "(#{splat_value.source}).to_a") end end
def frozen_string_literal?(node)
def frozen_string_literal?(node) FROZEN_STRING_LITERAL_TYPES.include?(node.type) && frozen_string_literals_enabled? end
def immutable_literal?(node)
def immutable_literal?(node) node.nil? || node.immutable_literal? end
def mutable_literal?(value)
def mutable_literal?(value) value && value.mutable_literal? end
def on_assignment(value)
def on_assignment(value) if style == :strict strict_check(value) else check(value) end end
def on_casgn(node)
def on_casgn(node) _scope, _const_name, value = *node on_assignment(value) end
def on_or_asgn(node)
def on_or_asgn(node) lhs, value = *node return unless lhs && lhs.casgn_type? on_assignment(value) end
def requires_parentheses?(node)
def requires_parentheses?(node) node.range_type? || (node.send_type? && node.loc.dot.nil?) end
def strict_check(value)
def strict_check(value) return if immutable_literal?(value) return if operation_produces_immutable_object?(value) return if frozen_string_literal?(value) add_offense(value) end