Skip to content

Commit e9852c9

Browse files
committed
Merge pull request rails#25681 from willnet/fix-thread_mattr_accessor
Fix `thread_mattr_accessor` share variable superclass with subclass
2 parents 628474f + 3529e58 commit e9852c9

File tree

3 files changed

+48
-4
lines changed

3 files changed

+48
-4
lines changed

activesupport/CHANGELOG.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,31 @@
1+
* Fix `thread_mattr_accessor` subclass no longer overwrites parent.
2+
3+
Assigning a value to a subclass using `thread_mattr_accessor` no
4+
longer changes the value of the parent class. This brings the
5+
behavior inline with the documentation.
6+
7+
Given:
8+
9+
class Account
10+
thread_mattr_accessor :user
11+
end
12+
13+
class Customer < Account
14+
end
15+
16+
Account.user = "DHH"
17+
Customer.user = "Rafael"
18+
19+
Before:
20+
21+
Account.user # => "Rafael"
22+
23+
After:
24+
25+
Account.user # => "DHH"
26+
27+
*Shinichi Maeshima*
28+
129
* Since weeks are no longer converted to days, add `:weeks` to the list of
230
parts that `ActiveSupport::TimeWithZone` will recognize as possibly being
331
of variable duration to take account of DST transitions.

activesupport/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,14 @@ def thread_mattr_reader(*syms)
4141
raise NameError.new("invalid attribute name: #{sym}") unless /^[_A-Za-z]\w*$/.match?(sym)
4242
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
4343
def self.#{sym}
44-
Thread.current[:"attr_#{name}_#{sym}"]
44+
Thread.current["attr_"+ name + "_#{sym}"]
4545
end
4646
EOS
4747

4848
unless options[:instance_reader] == false || options[:instance_accessor] == false
4949
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
5050
def #{sym}
51-
Thread.current[:"attr_#{name}_#{sym}"]
51+
Thread.current["attr_"+ self.class.name + "_#{sym}"]
5252
end
5353
EOS
5454
end
@@ -80,14 +80,14 @@ def thread_mattr_writer(*syms)
8080
raise NameError.new("invalid attribute name: #{sym}") unless /^[_A-Za-z]\w*$/.match?(sym)
8181
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
8282
def self.#{sym}=(obj)
83-
Thread.current[:"attr_#{name}_#{sym}"] = obj
83+
Thread.current["attr_"+ name + "_#{sym}"] = obj
8484
end
8585
EOS
8686

8787
unless options[:instance_writer] == false || options[:instance_accessor] == false
8888
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
8989
def #{sym}=(obj)
90-
Thread.current[:"attr_#{name}_#{sym}"] = obj
90+
Thread.current["attr_"+ self.class.name + "_#{sym}"] = obj
9191
end
9292
EOS
9393
end

activesupport/test/core_ext/module/attribute_accessor_per_thread_test.rb

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@ def setup
88
thread_mattr_accessor :bar, instance_writer: false
99
thread_mattr_reader :shaq, instance_reader: false
1010
thread_mattr_accessor :camp, instance_accessor: false
11+
12+
def self.name; "MyClass" end
13+
end
14+
15+
@subclass = Class.new(@class) do
16+
def self.name; "SubMyClass" end
1117
end
1218

1319
@object = @class.new
@@ -112,4 +118,14 @@ def test_should_return_same_value_by_class_or_instance_accessor
112118

113119
assert_equal @class.foo, @object.foo
114120
end
121+
122+
def test_should_not_affect_superclass_if_subclass_set_value
123+
@class.foo = "super"
124+
assert_equal @class.foo, "super"
125+
assert_nil @subclass.foo
126+
127+
@subclass.foo = "sub"
128+
assert_equal @class.foo, "super"
129+
assert_equal @subclass.foo, "sub"
130+
end
115131
end

0 commit comments

Comments
 (0)