Yet another tiny library to tackle this problem.
Install with: gem install schoefmax-tlattr_accessors --source=https://gems.github.com
require 'rubygems' require 'tlattr_accessors' class ThreadExample extend ThreadLocalAccessors tlattr_accessor :foo def test self.foo = "bla" Thread.new { puts foo # prints "nil" self.foo = "blubb" puts foo # prints "blubb" }.join puts foo # prints "bla" end end ThreadExample.new.test
If you want to enable them globally, add this somewhere (e.g. an initializer in Rails)
Object.send :extend, ThreadLocalAccessors
Adding true
as last parameter will cause the first value set on the attribute to act as default value for all other threads:
tlattr_accessor :yeah, :baby, true def test_default self.yeah = "bla" Thread.new { puts yeah # prints "bla" puts baby # prints "nil" self.baby = "blubb" self.yeah = "blabla" }.join puts yeah # prints "bla" puts baby # prints "blubb" end
This gem doesn’t support tlattr
or tlattr_reader|writer
for the simple reason that they don’t make any sense here (you don’t have an “instance variable”, so you need both methods). If you want to hide one of them from your API, you can always make them private:
tlattr_accessor :foo private :foo= # hide the setter
The Thread.current
-Hash is a global namespace. Using it to store thread-local variables safely requires carefully crafted keys, which tend to be rather expensive to compute. This hurts performance if the attribute is accessed frequently. Therefore, this library uses a different approach, which is a lot faster: The values are stored in a separate hash which is keyed by the object_id of the thread. Finalizers make sure no memory is leaked when threads finish (see the spec).
If you haven’t already, install the rspec gem, then run:
spec spec
© 2009, Max Schoefmann <max (a) pragmatic-it de> Released under the MIT license