Simplify accessing Thread.current variables.
Example:
class Foo include Innate::StateAccessor state_accessor :session def calculate session[:num1] + session[:num2] end end
Foo#calculate can now be called from anywhere in your application and it will have direct access to the session in the current request/response cycle in a thread-safe way without the need to explicitly pass the session along.
Iterate over the names and yield accordingly. names are either objects responding to # or hashes.
It’s only used within this module to make the code readable.
Used below.
# File lib/innate/state/accessor.rb, line 29 29: def self.each(*names) 30: names.each do |name| 31: if name.respond_to?(:to_hash) 32: name.to_hash.each do |key, meth| 33: yield(key.to_sym, meth.to_sym) 34: end 35: else 36: key = meth = name.to_sym 37: yield(key, meth) 38: end 39: end 40: end
Combined state_writer and state_reader. initializer is a block that may be given and its result will be the new value in case the method created by state_reader was never called before and the value wasn’t set before.
Example:
state_accessor(:session) state_accessor(:user){ session[:user] }
# File lib/innate/state/accessor.rb, line 52 52: def state_accessor(*names, &initializer) 53: state_writer(*names) 54: state_reader(*names, &initializer) 55: end
Reader accessor for Thread.current[key]
Example:
class Foo include Innate::StateAccessor state_reader(:session) state_reader(:random){ rand(100_000) } def calculate val1 = session[:num1] + session[:num2] + random val2 = session[:num1] + session[:num2] + random val1 == val2 # => true end end
NOTE:
If given +initializer+, there will be some performance impact since we cannot use class_eval and have to use define_method instead, we also have to check every time whether the initializer was executed already. In 1.8.x the overhead of define_method is 3x that of class_eval/def In 1.9.1 the overhead of define_method is 1.5x that of class_eval/def This may only be an issue for readers that are called a lot of times.
# File lib/innate/state/accessor.rb, line 114 114: def state_reader(*names, &initializer) 115: StateAccessor.each(*names) do |key, meth| 116: if initializer 117: define_method(meth) do 118: unless Thread.current.key?(key) 119: Thread.current[key] = instance_eval(&initializer) 120: else 121: Thread.current[key] 122: end 123: end 124: else 125: class_eval("def %s; Thread.current[%p]; end" % [meth, key]) 126: end 127: end 128: end
Writer accessor to Thread.current[key]=
Example: class Foo include Innate::StateAccessor state_writer(:result) def calculate self.result = 42 end end class Bar include Innate::StateAccessor state_reader(:result) def calculcate result * result end end Foo.new.calculate # => 42 Bar.new.calculate # => 1764
# File lib/innate/state/accessor.rb, line 82 82: def state_writer(*names) 83: StateAccessor.each(*names) do |key, meth| 84: class_eval("def %s=(obj) Thread.current[%p] = obj; end" % [meth, key]) 85: end 86: end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.