Module: Innate::StateAccessor
- Included in:
- Trinity
- Defined in:
- /home/manveru/github/ramaze/ramaze.net/tmp/git/innate/lib/innate/state/accessor.rb
Overview
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.
Class Method Summary (collapse)
-
+ (Object) each(*names)
Iterate over the names and yield accordingly.
Instance Method Summary (collapse)
-
- (Object) state_accessor(*names, &initializer)
Combined state_writer and state_reader.
-
- (Object) state_reader(*names, &initializer)
Reader accessor for Thread.current[key].
-
- (Object) state_writer(*names)
Writer accessor to Thread.current[key]=.
Class Method Details
+ (Object) each(*names)
Iterate over the names and yield accordingly. names are either objects responding to #to_sym or hashes.
It's only used within this module to make the code readable.
Used below.
29 30 31 32 33 34 35 36 37 38 39 40 |
# File '/home/manveru/github/ramaze/ramaze.net/tmp/git/innate/lib/innate/state/accessor.rb', line 29 def self.each(*names) names.each do |name| if name.respond_to?(:to_hash) name.to_hash.each do |key, meth| yield(key.to_sym, meth.to_sym) end else key = meth = name.to_sym yield(key, meth) end end end |
Instance Method Details
- (Object) state_accessor(*names, &initializer)
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] }
52 53 54 55 |
# File '/home/manveru/github/ramaze/ramaze.net/tmp/git/innate/lib/innate/state/accessor.rb', line 52 def state_accessor(*names, &initializer) state_writer(*names) state_reader(*names, &initializer) end |
- (Object) state_reader(*names, &initializer)
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.
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
# File '/home/manveru/github/ramaze/ramaze.net/tmp/git/innate/lib/innate/state/accessor.rb', line 114 def state_reader(*names, &initializer) StateAccessor.each(*names) do |key, meth| if initializer define_method(meth) do unless Thread.current.key?(key) Thread.current[key] = instance_eval(&initializer) else Thread.current[key] end end else class_eval("def %s; Thread.current[%p]; end" % [meth, key]) end end end |
- (Object) state_writer(*names)
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
82 83 84 85 86 |
# File '/home/manveru/github/ramaze/ramaze.net/tmp/git/innate/lib/innate/state/accessor.rb', line 82 def state_writer(*names) StateAccessor.each(*names) do |key, meth| class_eval("def %s=(obj) Thread.current[%p] = obj; end" % [meth, key]) end end |