Module | ThreadLocalAccessors |
In: |
lib/tlattr_accessors.rb
|
Creates thread-local accessors for the given attribute name.
tlattr_accessor :my_attr, :another_attr
You can make the attribute inherit the first value that was set on it in any thread:
tlattr_accessor :my_attr, true def initialize self.my_attr = "foo" Thread.new do puts self.my_attr # => "foo" (instead of nil) end.join end
# File lib/tlattr_accessors.rb, line 21 21: def tlattr_accessor(*names) 22: first_is_default = names.pop if [true, false].include?(names.last) 23: names.each do |name| 24: ivar = "@_tlattr_#{name}" 25: class_eval %Q{ 26: def #{name} 27: if #{ivar} 28: #{ivar}[Thread.current.object_id] 29: else 30: nil 31: end 32: end 33: 34: def #{name}=(val) 35: #{ivar} = Hash.new #{'{|h, k| h[k] = val}' if first_is_default} unless #{ivar} 36: thread_id = Thread.current.object_id 37: unless #{ivar}.has_key?(thread_id) 38: ObjectSpace.define_finalizer(Thread.current, lambda { #{ivar}.delete(thread_id) }) 39: end 40: #{ivar}[thread_id] = val 41: end 42: }, __FILE__, __LINE__ 43: end 44: end