Module: When::Parts::MethodCash
- Included in:
- Coordinates::Temporal, Ephemeris::Formula
- Defined in:
- lib/when_exe/parts/method_cash.rb
Overview
メソッドの実行結果をキャッシュし処理の高速化を行う
fn というメソッドをキャッシュ化
* fn
a_to_b と b_to_a という互いに逆関数のメソッドをキャッシュ化
* a_to_b
特記事項
Argument identification
The eql? method of When::TM::(Temporal)Position is not overridden.
It seems that the cost of identification of the argument exceeds the merit of the method cash.
I do not recommend the methodcash to the method which takes
When::TM::(Temporal)Position as an argument.
Multi-thread critical situation
There is a problem in consistency of hash when this function is used in multi-thread environment.
If the initialize method sets Mutex in instance variable @_m_cash_lock_,
this function gives up use of hash in the critical situation.
class Foo
include MethodCash
def initialize
...
@_m_cash_lock_ = Mutex.new
...
end
end
Instance Method Summary collapse
-
#method_missing(name, *args, &block) ⇒ void
最初に発生する method_missing で、キャッシュ機能を登録する.
- #method_missing_ ⇒ Object
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(name, *args, &block) ⇒ void
This method returns an undefined value.
最初に発生する method_missing で、キャッシュ機能を登録する
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/when_exe/parts/method_cash.rb', line 65 def method_missing(name, *args, &block) return method_missing_(name, *args, &block) unless respond_to?("#{name}_", true) if ((name.to_s =~ /^(_*)(.+?)_to_(.+)$/) && respond_to?("#{$1}#{$3}_to_#{$2}_", true)) prefix, from, to = $~[1..3] begin if (@_m_cash_lock_) return send("#{prefix}#{from}_to_#{to}_", *args, &block) unless @_m_cash_lock_.try_lock unlock = "ensure ; @_m_cash_lock_.locked? && @_m_cash_lock_.unlock" end [[from, to],[to, from]].each do |pair| a, b = pair lock = @_m_cash_lock_ ? " return #{prefix}#{a}_to_#{b}_(*args) unless @_m_cash_lock_.try_lock" : '' instance_eval %Q{ def #{prefix}#{a}_to_#{b}(*args) key = _key_simplefy(args) inv = @_m_cash_["#{prefix}#{a}_to_#{b}"][key] return inv if inv begin #{lock} inv = #{prefix}#{a}_to_#{b}_(*args) @_m_cash_["#{prefix}#{b}_to_#{a}"][_key_simplefy(inv)] = args @_m_cash_["#{prefix}#{a}_to_#{b}"][key] = inv return inv #{unlock} end end } end key = _key_simplefy(args) inv = send("#{prefix}#{from}_to_#{to}_", *args) @_m_cash_ ||= {} @_m_cash_["#{prefix}#{to}_to_#{from}"] ||= {} @_m_cash_["#{prefix}#{from}_to_#{to}"] ||= {} @_m_cash_["#{prefix}#{to}_to_#{from}"][_key_simplefy(inv)] = args @_m_cash_["#{prefix}#{from}_to_#{to}"][key] = inv return inv ensure @_m_cash_lock_ && @_m_cash_lock_.locked? && @_m_cash_lock_.unlock end else begin respond = respond_to?("#{name}_setup", true) setup = respond ? "#{name}_setup(key, *args)" : "(@_m_cash_[\"#{name}\"][key] = #{name}_(*args))" if (@_m_cash_lock_) return send("#{name}_", *args, &block) unless @_m_cash_lock_.try_lock lock = " return #{name}_(*args) unless @_m_cash_lock_.try_lock" unlock = "ensure ; @_m_cash_lock_.locked? && @_m_cash_lock_.unlock" end instance_eval %Q{ def #{name}(*args) key = _key_simplefy(args) ret = @_m_cash_["#{name}"][key] return ret if ret begin #{lock} return #{setup} #{unlock} end end } key = _key_simplefy(args) @_m_cash_ ||= {} @_m_cash_["#{name}"] ||= {} if (respond) return send("#{name}_setup", key, *args) else return(@_m_cash_["#{name}"][key] ||= send("#{name}_", *args)) end ensure @_m_cash_lock_ && @_m_cash_lock_.locked? && @_m_cash_lock_.unlock end end end |
Instance Method Details
#method_missing_ ⇒ Object
54 |
# File 'lib/when_exe/parts/method_cash.rb', line 54 alias :method_missing_ :method_missing |