Method: Module#thread_mattr_reader
- Defined in:
- lib/active_support/core_ext/module/attribute_accessors_per_thread.rb
#thread_mattr_reader(*syms, instance_reader: true, instance_accessor: true, default: nil) ⇒ Object Also known as: thread_cattr_reader
Defines a per-thread class attribute and creates class and instance reader methods. The underlying per-thread class variable is set to nil, if it is not previously defined.
module Current
thread_mattr_reader :user
end
Current.user = "DHH"
Current.user # => "DHH"
Thread.new { Current.user }.value # => nil
The attribute name must be a valid method name in Ruby.
module Foo
thread_mattr_reader :"1_Badname"
end
# => NameError: invalid attribute name: 1_Badname
To omit the instance reader method, pass instance_reader: false or instance_accessor: false.
class Current
thread_mattr_reader :user, instance_reader: false
end
Current.new.user # => NoMethodError
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/active_support/core_ext/module/attribute_accessors_per_thread.rb', line 41 def thread_mattr_reader(*syms, instance_reader: true, instance_accessor: true, default: nil) # :nodoc: syms.each do |sym| raise NameError.new("invalid attribute name: #{sym}") unless /^[_A-Za-z]\w*$/.match?(sym) # The following generated method concatenates `object_id` because we want # subclasses to maintain independent values. if default.nil? class_eval(<<-EOS, __FILE__, __LINE__ + 1) def self.#{sym} @__thread_mattr_#{sym} ||= "attr_#{sym}_\#{object_id}" ::ActiveSupport::IsolatedExecutionState[@__thread_mattr_#{sym}] end EOS else default = default.dup.freeze unless default.frozen? singleton_class.define_method("#{sym}_default_value") { default } class_eval(<<-EOS, __FILE__, __LINE__ + 1) def self.#{sym} @__thread_mattr_#{sym} ||= "attr_#{sym}_\#{object_id}" value = ::ActiveSupport::IsolatedExecutionState[@__thread_mattr_#{sym}] if value.nil? && !::ActiveSupport::IsolatedExecutionState.key?(@__thread_mattr_#{sym}) ::ActiveSupport::IsolatedExecutionState[@__thread_mattr_#{sym}] = #{sym}_default_value else value end end EOS end if instance_reader && instance_accessor class_eval(<<-EOS, __FILE__, __LINE__ + 1) def #{sym} self.class.#{sym} end EOS end end end |