Class: RuboCop::Cop::ThreadSafety::MutableClassInstanceVariable
- Inherits:
-
RuboCop::Cop
- Object
- RuboCop::Cop
- RuboCop::Cop::ThreadSafety::MutableClassInstanceVariable
- Includes:
- ConfigurableEnforcedStyle, FrozenStringLiteral
- Defined in:
- lib/rubocop/cop/thread_safety/mutable_class_instance_variable.rb
Overview
This cop 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-hq/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.'
Instance Method Summary collapse
- #autocorrect(node) ⇒ Object
- #on_ivasgn(node) ⇒ Object
- #on_masgn(node) ⇒ Object
- #on_or_asgn(node) ⇒ Object
Instance Method Details
#autocorrect(node) ⇒ Object
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/rubocop/cop/thread_safety/mutable_class_instance_variable.rb', line 109 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 |
#on_ivasgn(node) ⇒ Object
81 82 83 84 85 86 |
# File 'lib/rubocop/cop/thread_safety/mutable_class_instance_variable.rb', line 81 def on_ivasgn(node) return unless in_class?(node) _, value = *node on_assignment(value) end |
#on_masgn(node) ⇒ Object
96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/rubocop/cop/thread_safety/mutable_class_instance_variable.rb', line 96 def on_masgn(node) return unless in_class?(node) mlhs, values = *node 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
88 89 90 91 92 93 94 |
# File 'lib/rubocop/cop/thread_safety/mutable_class_instance_variable.rb', line 88 def on_or_asgn(node) lhs, value = *node return unless lhs&.ivasgn_type? return unless in_class?(node) on_assignment(value) end |