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. --- .../core_ext/module/attribute_accessors_per_thread.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'activesupport/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb') diff --git a/activesupport/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb b/activesupport/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb index 7015333f7c..946be64f1c 100644 --- a/activesupport/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +++ b/activesupport/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb @@ -41,14 +41,14 @@ class Module raise NameError.new("invalid attribute name: #{sym}") unless /^[_A-Za-z]\w*$/.match?(sym) class_eval(<<-EOS, __FILE__, __LINE__ + 1) def self.#{sym} - Thread.current[:"attr_#{name}_#{sym}"] + Thread.current["attr_"+ name + "_#{sym}"] end EOS unless options[:instance_reader] == false || options[:instance_accessor] == false class_eval(<<-EOS, __FILE__, __LINE__ + 1) def #{sym} - Thread.current[:"attr_#{name}_#{sym}"] + Thread.current["attr_"+ self.class.name + "_#{sym}"] end EOS end @@ -80,14 +80,14 @@ class Module raise NameError.new("invalid attribute name: #{sym}") unless /^[_A-Za-z]\w*$/.match?(sym) class_eval(<<-EOS, __FILE__, __LINE__ + 1) def self.#{sym}=(obj) - Thread.current[:"attr_#{name}_#{sym}"] = obj + Thread.current["attr_"+ name + "_#{sym}"] = obj end EOS unless options[:instance_writer] == false || options[:instance_accessor] == false class_eval(<<-EOS, __FILE__, __LINE__ + 1) def #{sym}=(obj) - Thread.current[:"attr_#{name}_#{sym}"] = obj + Thread.current["attr_"+ self.class.name + "_#{sym}"] = obj end EOS end -- cgit v1.2.3