From 3529e58efd21697cb5559fe622df8013179625a2 Mon Sep 17 00:00:00 2001 From: willnet Date: Mon, 4 Jul 2016 18:17:20 +0900 Subject: Fix `thread_mattr_accessor` share variable superclass with subclass The current implementation of `thread_mattr_accessor` set variable sharing superclass with subclass. So the method doesn't work as documented. Precondition class Account thread_mattr_accessor :user end class Customer < Account end Account.user = "DHH" Account.user #=> "DHH" Customer.user = "Rafael" Customer.user # => "Rafael" Documented behavior Account.user # => "DHH" Actual behavior Account.user # => "Rafael" Current implementation set variable statically likes `Thread[:attr_Account_user]`, and customer also use it. Make variable name dynamic to use own thread-local variable. --- .../module/attribute_accessor_per_thread_test.rb | 28 ++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) (limited to 'activesupport/test/core_ext/module/attribute_accessor_per_thread_test.rb') diff --git a/activesupport/test/core_ext/module/attribute_accessor_per_thread_test.rb b/activesupport/test/core_ext/module/attribute_accessor_per_thread_test.rb index a9fd878b80..cdde6434f2 100644 --- a/activesupport/test/core_ext/module/attribute_accessor_per_thread_test.rb +++ b/activesupport/test/core_ext/module/attribute_accessor_per_thread_test.rb @@ -8,6 +8,16 @@ class ModuleAttributeAccessorPerThreadTest < ActiveSupport::TestCase thread_mattr_accessor :bar, instance_writer: false thread_mattr_reader :shaq, instance_reader: false thread_mattr_accessor :camp, instance_accessor: false + + def self.name + 'MyClass' + end + end + + @subclass = Class.new(@class) do + def self.name + 'SubMyClass' + end end @object = @class.new @@ -65,15 +75,15 @@ class ModuleAttributeAccessorPerThreadTest < ActiveSupport::TestCase threads << Thread.new do @class.foo = 'other things' sleep 1 - assert_equal 'other things', @class.foo + assert_equal 'other things', @class.foo end - + threads << Thread.new do @class.foo = 'really other things' sleep 1 - assert_equal 'really other things', @class.foo + assert_equal 'really other things', @class.foo end - + threads.each { |t| t.join } end @@ -112,4 +122,14 @@ class ModuleAttributeAccessorPerThreadTest < ActiveSupport::TestCase assert_equal @class.foo, @object.foo end + + def test_should_not_affect_superclass_if_subclass_set_value + @class.foo = 'super' + assert_equal @class.foo, 'super' + assert_nil @subclass.foo + + @subclass.foo = 'sub' + assert_equal @class.foo, 'super' + assert_equal @subclass.foo, 'sub' + end end -- cgit v1.2.3