| 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