Class: RuboCop::Cop::ThreadSafety::MutableClassInstanceVariable
- Inherits:
-
Base
- Object
- Base
- RuboCop::Cop::ThreadSafety::MutableClassInstanceVariable
- Extended by:
- AutoCorrector
- Includes:
- ConfigurableEnforcedStyle, FrozenStringLiteral, OperationWithThreadsafeResult
- Defined in:
- lib/rubocop/cop/thread_safety/mutable_class_instance_variable.rb
Overview
Checks whether some class instance variable isn’t a mutable literal (e.g. array or hash).
It is based on Style/MutableConstant from RuboCop. See github.com/rubocop/rubocop/blob/master/lib/rubocop/cop/style/mutable_constant.rb
Class instance variables are a risk to threaded code as they are shared between threads. A mutable object such as an array or hash may be updated via an attr_reader so would not be detected by the ThreadSafety/ClassAndModuleAttributes cop.
Strict mode can be used to freeze all class instance variables, rather than just literals. Strict mode is considered an experimental feature. It has not been updated with an exhaustive list of all methods that will produce frozen objects so there is a decent chance of getting some false positives. Luckily, there is no harm in freezing an already frozen object.
Constant Summary collapse
- MSG =
'Freeze mutable objects assigned to class instance variables.'
- FROZEN_STRING_LITERAL_TYPES_RUBY27 =
%i[str dstr].freeze
- FROZEN_STRING_LITERAL_TYPES_RUBY30 =
%i[str].freeze
Instance Method Summary collapse
- #autocorrect(corrector, node) ⇒ Object
- #on_ivasgn(node) ⇒ Object
- #on_masgn(node) ⇒ Object
- #on_or_asgn(node) ⇒ Object
Methods included from OperationWithThreadsafeResult
#operation_produces_threadsafe_object?
Instance Method Details
#autocorrect(corrector, node) ⇒ Object
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/rubocop/cop/thread_safety/mutable_class_instance_variable.rb', line 112 def autocorrect(corrector, node) expr = node.source_range 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 |
#on_ivasgn(node) ⇒ Object
86 87 88 89 90 |
# File 'lib/rubocop/cop/thread_safety/mutable_class_instance_variable.rb', line 86 def on_ivasgn(node) return unless in_class?(node) on_assignment(node.expression) end |
#on_masgn(node) ⇒ Object
99 100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/rubocop/cop/thread_safety/mutable_class_instance_variable.rb', line 99 def on_masgn(node) return unless in_class?(node) mlhs, values = *node # rubocop:disable InternalAffairs/NodeDestructuring return unless values.array_type? mlhs.to_a.zip(values.to_a).each do |lhs, value| next unless lhs.ivasgn_type? on_assignment(value) end end |
#on_or_asgn(node) ⇒ Object
92 93 94 95 96 97 |
# File 'lib/rubocop/cop/thread_safety/mutable_class_instance_variable.rb', line 92 def on_or_asgn(node) return unless node.assignment_node.ivasgn_type? return unless in_class?(node) on_assignment(node.expression) end |