when_exe 0.4.2 → 0.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +24 -23
- data/lib/when_exe/ephemeris/moon.rb +333 -333
- data/lib/when_exe/linkeddata.rb +0 -1
- data/lib/when_exe/locales/encoding_conversion.rb +134 -134
- data/lib/when_exe/locales/iast.rb +90 -90
- data/lib/when_exe/locales/transliteration_table.rb +62 -62
- data/lib/when_exe/parts/method_cash.rb +224 -224
- data/lib/when_exe/region/chinese/calendars.rb +1016 -1016
- data/lib/when_exe/region/geologicalage.rb +1 -1
- data/lib/when_exe/region/japanese/calendars.rb +397 -397
- data/lib/when_exe/region/japanese/eclipses.rb +1194 -1194
- data/lib/when_exe/region/japanese/nihon_shoki.rb +70 -70
- data/lib/when_exe/region/korean.rb +384 -384
- data/lib/when_exe/region/ryukyu.rb +101 -101
- data/lib/when_exe/tmposition.rb +2 -2
- data/lib/when_exe/tmreference.rb +3 -3
- data/lib/when_exe/version.rb +1 -1
- data/test/scripts/geometric_complex.rb +41 -41
- data/test/scripts/korea.rb +59 -59
- data/test/scripts/thai.rb +36 -36
- data/test/test/basictypes.rb +431 -431
- data/test/test/calendarnote.rb +86 -86
- data/test/test/calendartypes.rb +97 -97
- data/test/test/coordinates.rb +397 -397
- data/test/test/ephemeris.rb +115 -115
- data/test/test/ephemeris/moon.rb +14 -14
- data/test/test/ephemeris/planets.rb +14 -14
- data/test/test/ephemeris/sun.rb +14 -14
- data/test/test/inspect.rb +153 -153
- data/test/test/parts.rb +488 -488
- data/test/test/region/armenian.rb +20 -20
- data/test/test/region/bahai.rb +58 -58
- data/test/test/region/balinese.rb +34 -34
- data/test/test/region/chinese.rb +229 -229
- data/test/test/region/christian.rb +226 -226
- data/test/test/region/coptic.rb +27 -27
- data/test/test/region/discordian.rb +20 -20
- data/test/test/region/french.rb +33 -33
- data/test/test/region/geologicalage.rb +17 -17
- data/test/test/region/iran.rb +54 -54
- data/test/test/region/islamic.rb +54 -54
- data/test/test/region/japanese.rb +261 -261
- data/test/test/region/jewish.rb +63 -63
- data/test/test/region/shire.rb +58 -58
- data/test/test/region/swedish.rb +45 -45
- data/test/test/region/thai.rb +116 -116
- data/test/test/region/tibetan.rb +30 -30
- data/test/test/region/vietnamese.rb +102 -102
- data/test/test/region/zoroastrian.rb +58 -58
- data/test/test/timestandard.rb +81 -81
- data/test/test/tmobjects.rb +402 -402
- data/test/test/tmreference.rb +157 -157
- metadata +4 -88
@@ -1,62 +1,62 @@
|
|
1
|
-
# -*- coding: utf-8 -*-
|
2
|
-
=begin
|
3
|
-
Copyright (C) 2014 Takashi SUGA
|
4
|
-
|
5
|
-
You may use and/or modify this file according to the license described in the LICENSE.txt file included in this archive.
|
6
|
-
=end
|
7
|
-
|
8
|
-
module When
|
9
|
-
module Locale
|
10
|
-
class << self
|
11
|
-
|
12
|
-
#
|
13
|
-
# Generate Regexp for transliteration
|
14
|
-
#
|
15
|
-
# @param [Hash] hash transliteration table
|
16
|
-
#
|
17
|
-
# @return [Regexp] Regexp for transliteration
|
18
|
-
#
|
19
|
-
def transliteration_keys(hash)
|
20
|
-
Regexp.new((hash.keys.sort_by {|key| -key.length} + ['%.*?[A-Za-z]']).join('|'))
|
21
|
-
end
|
22
|
-
|
23
|
-
#
|
24
|
-
# Generate Hash of {locale=>Regexp} for transliteration
|
25
|
-
#
|
26
|
-
# @param [Hash] hash transliteration table hash
|
27
|
-
#
|
28
|
-
# @return [Hash{String=>Regexp}] Hash of {locale=>Regexp} for transliteration
|
29
|
-
#
|
30
|
-
def transliteration_keys_hash(hash)
|
31
|
-
Hash[*(hash.keys.map {|locale|
|
32
|
-
[locale, transliteration_keys(hash[locale])]
|
33
|
-
}).flatten]
|
34
|
-
end
|
35
|
-
|
36
|
-
alias :_method_missing :method_missing
|
37
|
-
|
38
|
-
#
|
39
|
-
# Registlation of conversion method
|
40
|
-
#
|
41
|
-
def method_missing(name, *args, &block)
|
42
|
-
table_name = name.to_s.upcase
|
43
|
-
return _method_missing(name, *args, &block) unless table_name !~ /_/ && const_defined?(table_name)
|
44
|
-
table_obj = const_get(table_name)
|
45
|
-
default = table_obj.keys.first
|
46
|
-
locale = args[1] || default
|
47
|
-
const_set(table_name + '_keys', transliteration_keys_hash(table_obj)) unless const_defined?(table_name + '_keys')
|
48
|
-
return send(name, args[0], locale) if respond_to?(name)
|
49
|
-
instance_eval %Q{
|
50
|
-
def #{name}(string, locale='#{default}')
|
51
|
-
string.gsub(#{table_name}_keys[locale]) do |code|
|
52
|
-
#{table_name}[locale][code] || code
|
53
|
-
end
|
54
|
-
end
|
55
|
-
}
|
56
|
-
args[0].gsub(const_get("#{table_name}_keys")[locale]) do |code|
|
57
|
-
table_obj[locale][code] || code
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
=begin
|
3
|
+
Copyright (C) 2014 Takashi SUGA
|
4
|
+
|
5
|
+
You may use and/or modify this file according to the license described in the LICENSE.txt file included in this archive.
|
6
|
+
=end
|
7
|
+
|
8
|
+
module When
|
9
|
+
module Locale
|
10
|
+
class << self
|
11
|
+
|
12
|
+
#
|
13
|
+
# Generate Regexp for transliteration
|
14
|
+
#
|
15
|
+
# @param [Hash] hash transliteration table
|
16
|
+
#
|
17
|
+
# @return [Regexp] Regexp for transliteration
|
18
|
+
#
|
19
|
+
def transliteration_keys(hash)
|
20
|
+
Regexp.new((hash.keys.sort_by {|key| -key.length} + ['%.*?[A-Za-z]']).join('|'))
|
21
|
+
end
|
22
|
+
|
23
|
+
#
|
24
|
+
# Generate Hash of {locale=>Regexp} for transliteration
|
25
|
+
#
|
26
|
+
# @param [Hash] hash transliteration table hash
|
27
|
+
#
|
28
|
+
# @return [Hash{String=>Regexp}] Hash of {locale=>Regexp} for transliteration
|
29
|
+
#
|
30
|
+
def transliteration_keys_hash(hash)
|
31
|
+
Hash[*(hash.keys.map {|locale|
|
32
|
+
[locale, transliteration_keys(hash[locale])]
|
33
|
+
}).flatten]
|
34
|
+
end
|
35
|
+
|
36
|
+
alias :_method_missing :method_missing
|
37
|
+
|
38
|
+
#
|
39
|
+
# Registlation of conversion method
|
40
|
+
#
|
41
|
+
def method_missing(name, *args, &block)
|
42
|
+
table_name = name.to_s.upcase
|
43
|
+
return _method_missing(name, *args, &block) unless table_name !~ /_/ && const_defined?(table_name)
|
44
|
+
table_obj = const_get(table_name)
|
45
|
+
default = table_obj.keys.first
|
46
|
+
locale = args[1] || default
|
47
|
+
const_set(table_name + '_keys', transliteration_keys_hash(table_obj)) unless const_defined?(table_name + '_keys')
|
48
|
+
return send(name, args[0], locale) if respond_to?(name)
|
49
|
+
instance_eval %Q{
|
50
|
+
def #{name}(string, locale='#{default}')
|
51
|
+
string.gsub(#{table_name}_keys[locale]) do |code|
|
52
|
+
#{table_name}[locale][code] || code
|
53
|
+
end
|
54
|
+
end
|
55
|
+
}
|
56
|
+
args[0].gsub(const_get("#{table_name}_keys")[locale]) do |code|
|
57
|
+
table_obj[locale][code] || code
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -1,224 +1,224 @@
|
|
1
|
-
# -*- coding: utf-8 -*-
|
2
|
-
=begin
|
3
|
-
Copyright (C) 2011-2014 Takashi SUGA
|
4
|
-
|
5
|
-
You may use and/or modify this file according to the license described in the LICENSE.txt file included in this archive.
|
6
|
-
=end
|
7
|
-
|
8
|
-
module When
|
9
|
-
#
|
10
|
-
# 本ライブラリのための諸々の部品
|
11
|
-
#
|
12
|
-
module Parts
|
13
|
-
|
14
|
-
#
|
15
|
-
# == メソッドの実行結果をキャッシュし処理の高速化を行う
|
16
|
-
#
|
17
|
-
# === fn というメソッドをキャッシュ化
|
18
|
-
# * fn ではなく fn_ を定義しておく
|
19
|
-
# * fn メソッドが呼ばれると fn_ を実行し、{引数=>戻り値} を Hash に記憶する
|
20
|
-
# * 同じ引数で再度 fn メソッドが呼ばれると Hash から戻り値を取り出して返す
|
21
|
-
#
|
22
|
-
# === a_to_b と b_to_a という互いに逆関数のメソッドをキャッシュ化
|
23
|
-
# * a_to_b ではなく a_to_b_ , b_to_a ではなく b_to_a_ を定義しておく
|
24
|
-
# * a_to_b メソッドが呼ばれると a_to_b_ を実行し、{引数=>戻り値}, {戻り値=>引数}を Hash に記憶する
|
25
|
-
# * 同じ引数で再度 a_to_b メソッドが呼ばれると Hash から戻り値を取り出して返す
|
26
|
-
# * b_to_a メソッドが呼ばれ Hash に戻り値があれば Hash から戻り値を取り出して返す
|
27
|
-
#
|
28
|
-
# == 特記事項
|
29
|
-
#
|
30
|
-
# === Argument identification
|
31
|
-
# The eql? method of When::TM::(Temporal)Position is not overridden.
|
32
|
-
# It seems that the cost of identification of the argument exceeds the merit of the method cash.
|
33
|
-
# I do not recommend applying the methodcash to the method which takes
|
34
|
-
# When::TM::(Temporal)Position as an argument.
|
35
|
-
#
|
36
|
-
# === Multi-thread critical situation
|
37
|
-
# There is a problem in consistency of hash when this function is used in multi-thread environment.
|
38
|
-
# If the initialize method sets Mutex in instance variable @_m_cash_lock_,
|
39
|
-
# this function gives up use of hash in the critical situation.
|
40
|
-
#
|
41
|
-
# class Foo
|
42
|
-
# include MethodCash
|
43
|
-
#
|
44
|
-
# def initialize
|
45
|
-
# ...
|
46
|
-
# @_m_cash_lock_ = Mutex.new
|
47
|
-
# ...
|
48
|
-
# end
|
49
|
-
# end
|
50
|
-
#
|
51
|
-
# 参考 http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-list/47663
|
52
|
-
#
|
53
|
-
module MethodCash
|
54
|
-
|
55
|
-
# @private
|
56
|
-
Escape = {:to_str => true,
|
57
|
-
:to_ary => true,
|
58
|
-
:to_hash => true}
|
59
|
-
|
60
|
-
class << self
|
61
|
-
|
62
|
-
# '_' で終わるメソッドをキャッシュせずに毎回計算するか否か
|
63
|
-
#
|
64
|
-
# @return [Boolean] キャッシュしない true, キャッシュする false/nil
|
65
|
-
#
|
66
|
-
attr_accessor :direct
|
67
|
-
|
68
|
-
# When::Parts::MethodCash のグローバルな設定を行う
|
69
|
-
#
|
70
|
-
# @param [Hash] options 以下の通り
|
71
|
-
# @option options [Boolean] :direct '_' で終わるメソッドをキャッシュせずに毎回計算するか否か
|
72
|
-
# @option options [Hash{Symbol=>boolean}] :escape 毎回 method_missing を発生させるメソッドを true にする
|
73
|
-
# @option options [false, nil] :escape to_str, to_ary, to_hash のみ毎回 method_missing を発生させる
|
74
|
-
# @option options [true] :escape すべて毎回 method_missing を発生させる
|
75
|
-
#
|
76
|
-
# @return [void]
|
77
|
-
#
|
78
|
-
# @note When::TM::Calendar クラスの一部はキャッシュ使用を前提としているため :direct=>true では動作しません
|
79
|
-
#
|
80
|
-
def _setup_(options={})
|
81
|
-
@_setup_info = options
|
82
|
-
@direct = options[:direct]
|
83
|
-
case options[:escape]
|
84
|
-
when true
|
85
|
-
instance_eval %Q{
|
86
|
-
def escape(method)
|
87
|
-
true
|
88
|
-
end
|
89
|
-
}
|
90
|
-
when Hash
|
91
|
-
@escape = Escape.merge(options[:escape])
|
92
|
-
instance_eval %Q{
|
93
|
-
def escape(method)
|
94
|
-
@escape[method]
|
95
|
-
end
|
96
|
-
}
|
97
|
-
else
|
98
|
-
instance_eval %Q{
|
99
|
-
def escape(method)
|
100
|
-
Escape.key?(method)
|
101
|
-
end
|
102
|
-
}
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
# 設定情報を取得する
|
107
|
-
#
|
108
|
-
# @return [Hash] 設定情報
|
109
|
-
#
|
110
|
-
def _setup_info
|
111
|
-
@_setup_info ||= {}
|
112
|
-
end
|
113
|
-
|
114
|
-
# method_missing メソッドを forward するか否か
|
115
|
-
#
|
116
|
-
# @param [Symbol] method メソッドシンボル
|
117
|
-
#
|
118
|
-
# @return [boolean] true - しない, false/nil - する
|
119
|
-
#
|
120
|
-
def escape(method)
|
121
|
-
Escape.key?(method)
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
alias :method_missing_ :method_missing
|
126
|
-
|
127
|
-
#
|
128
|
-
# 最初に発生する method_missing で、キャッシュ機能を登録する
|
129
|
-
#
|
130
|
-
# @param [Symbol] name メソッド名
|
131
|
-
# @param [Array] args メソッド引数
|
132
|
-
# @param [block] block ブロック(省略可)
|
133
|
-
#
|
134
|
-
# @return [void]
|
135
|
-
#
|
136
|
-
def method_missing(name, *args, &block)
|
137
|
-
|
138
|
-
return method_missing_(name, *args, &block) unless respond_to?("#{name}_", true)
|
139
|
-
return send("#{name}_", *args, &block) if MethodCash.direct
|
140
|
-
|
141
|
-
if ((name.to_s =~ /\A(_*)(.+?)_to_(.+)\z/) && respond_to?("#{$1}#{$3}_to_#{$2}_", true))
|
142
|
-
prefix, from, to = $~[1..3]
|
143
|
-
begin
|
144
|
-
if (@_m_cash_lock_)
|
145
|
-
return send("#{prefix}#{from}_to_#{to}_", *args, &block) unless @_m_cash_lock_.try_lock
|
146
|
-
unlock = "ensure ; @_m_cash_lock_.locked? && @_m_cash_lock_.unlock"
|
147
|
-
end
|
148
|
-
[[from, to],[to, from]].each do |pair|
|
149
|
-
a, b = pair
|
150
|
-
lock = @_m_cash_lock_ ? " return #{prefix}#{a}_to_#{b}_(*args) unless @_m_cash_lock_.try_lock" : ''
|
151
|
-
instance_eval %Q{
|
152
|
-
def #{prefix}#{a}_to_#{b}(*args)
|
153
|
-
key = _key_simplefy(args)
|
154
|
-
inv = @_m_cash_["#{prefix}#{a}_to_#{b}"][key]
|
155
|
-
return inv if inv
|
156
|
-
begin
|
157
|
-
#{lock}
|
158
|
-
inv = #{prefix}#{a}_to_#{b}_(*args)
|
159
|
-
@_m_cash_["#{prefix}#{b}_to_#{a}"][_key_simplefy(inv)] = args
|
160
|
-
@_m_cash_["#{prefix}#{a}_to_#{b}"][key] = inv
|
161
|
-
return inv
|
162
|
-
#{unlock}
|
163
|
-
end
|
164
|
-
end
|
165
|
-
}
|
166
|
-
end
|
167
|
-
key = _key_simplefy(args)
|
168
|
-
inv = send("#{prefix}#{from}_to_#{to}_", *args)
|
169
|
-
@_m_cash_ ||= {}
|
170
|
-
@_m_cash_["#{prefix}#{to}_to_#{from}"] ||= {}
|
171
|
-
@_m_cash_["#{prefix}#{from}_to_#{to}"] ||= {}
|
172
|
-
@_m_cash_["#{prefix}#{to}_to_#{from}"][_key_simplefy(inv)] = args
|
173
|
-
@_m_cash_["#{prefix}#{from}_to_#{to}"][key] = inv
|
174
|
-
return inv
|
175
|
-
ensure
|
176
|
-
@_m_cash_lock_ && @_m_cash_lock_.locked? && @_m_cash_lock_.unlock
|
177
|
-
end
|
178
|
-
|
179
|
-
else
|
180
|
-
begin
|
181
|
-
respond = respond_to?("#{name}_setup", true)
|
182
|
-
setup = respond ? "#{name}_setup(key, *args)" :
|
183
|
-
"(@_m_cash_[\"#{name}\"][key] = #{name}_(*args))"
|
184
|
-
if (@_m_cash_lock_)
|
185
|
-
return send("#{name}_", *args, &block) unless @_m_cash_lock_.try_lock
|
186
|
-
lock = " return #{name}_(*args) unless @_m_cash_lock_.try_lock"
|
187
|
-
unlock = "ensure ; @_m_cash_lock_.locked? && @_m_cash_lock_.unlock"
|
188
|
-
end
|
189
|
-
instance_eval %Q{
|
190
|
-
def #{name}(*args)
|
191
|
-
key = _key_simplefy(args)
|
192
|
-
ret = @_m_cash_["#{name}"][key]
|
193
|
-
return ret if ret
|
194
|
-
begin
|
195
|
-
#{lock}
|
196
|
-
return #{setup}
|
197
|
-
#{unlock}
|
198
|
-
end
|
199
|
-
end
|
200
|
-
}
|
201
|
-
key = _key_simplefy(args)
|
202
|
-
@_m_cash_ ||= {}
|
203
|
-
@_m_cash_["#{name}"] ||= {}
|
204
|
-
if (respond)
|
205
|
-
return send("#{name}_setup", key, *args)
|
206
|
-
else
|
207
|
-
return(@_m_cash_["#{name}"][key] ||= send("#{name}_", *args))
|
208
|
-
end
|
209
|
-
ensure
|
210
|
-
@_m_cash_lock_ && @_m_cash_lock_.locked? && @_m_cash_lock_.unlock
|
211
|
-
end
|
212
|
-
end
|
213
|
-
end
|
214
|
-
|
215
|
-
private
|
216
|
-
|
217
|
-
def _key_simplefy(args)
|
218
|
-
key = args.kind_of?(Array) ? args.dup : args
|
219
|
-
key = key[0] while key.kind_of?(Array) && key.length<=1
|
220
|
-
return key
|
221
|
-
end
|
222
|
-
end
|
223
|
-
end
|
224
|
-
end
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
=begin
|
3
|
+
Copyright (C) 2011-2014 Takashi SUGA
|
4
|
+
|
5
|
+
You may use and/or modify this file according to the license described in the LICENSE.txt file included in this archive.
|
6
|
+
=end
|
7
|
+
|
8
|
+
module When
|
9
|
+
#
|
10
|
+
# 本ライブラリのための諸々の部品
|
11
|
+
#
|
12
|
+
module Parts
|
13
|
+
|
14
|
+
#
|
15
|
+
# == メソッドの実行結果をキャッシュし処理の高速化を行う
|
16
|
+
#
|
17
|
+
# === fn というメソッドをキャッシュ化
|
18
|
+
# * fn ではなく fn_ を定義しておく
|
19
|
+
# * fn メソッドが呼ばれると fn_ を実行し、{引数=>戻り値} を Hash に記憶する
|
20
|
+
# * 同じ引数で再度 fn メソッドが呼ばれると Hash から戻り値を取り出して返す
|
21
|
+
#
|
22
|
+
# === a_to_b と b_to_a という互いに逆関数のメソッドをキャッシュ化
|
23
|
+
# * a_to_b ではなく a_to_b_ , b_to_a ではなく b_to_a_ を定義しておく
|
24
|
+
# * a_to_b メソッドが呼ばれると a_to_b_ を実行し、{引数=>戻り値}, {戻り値=>引数}を Hash に記憶する
|
25
|
+
# * 同じ引数で再度 a_to_b メソッドが呼ばれると Hash から戻り値を取り出して返す
|
26
|
+
# * b_to_a メソッドが呼ばれ Hash に戻り値があれば Hash から戻り値を取り出して返す
|
27
|
+
#
|
28
|
+
# == 特記事項
|
29
|
+
#
|
30
|
+
# === Argument identification
|
31
|
+
# The eql? method of When::TM::(Temporal)Position is not overridden.
|
32
|
+
# It seems that the cost of identification of the argument exceeds the merit of the method cash.
|
33
|
+
# I do not recommend applying the methodcash to the method which takes
|
34
|
+
# When::TM::(Temporal)Position as an argument.
|
35
|
+
#
|
36
|
+
# === Multi-thread critical situation
|
37
|
+
# There is a problem in consistency of hash when this function is used in multi-thread environment.
|
38
|
+
# If the initialize method sets Mutex in instance variable @_m_cash_lock_,
|
39
|
+
# this function gives up use of hash in the critical situation.
|
40
|
+
#
|
41
|
+
# class Foo
|
42
|
+
# include MethodCash
|
43
|
+
#
|
44
|
+
# def initialize
|
45
|
+
# ...
|
46
|
+
# @_m_cash_lock_ = Mutex.new
|
47
|
+
# ...
|
48
|
+
# end
|
49
|
+
# end
|
50
|
+
#
|
51
|
+
# 参考 http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-list/47663
|
52
|
+
#
|
53
|
+
module MethodCash
|
54
|
+
|
55
|
+
# @private
|
56
|
+
Escape = {:to_str => true,
|
57
|
+
:to_ary => true,
|
58
|
+
:to_hash => true}
|
59
|
+
|
60
|
+
class << self
|
61
|
+
|
62
|
+
# '_' で終わるメソッドをキャッシュせずに毎回計算するか否か
|
63
|
+
#
|
64
|
+
# @return [Boolean] キャッシュしない true, キャッシュする false/nil
|
65
|
+
#
|
66
|
+
attr_accessor :direct
|
67
|
+
|
68
|
+
# When::Parts::MethodCash のグローバルな設定を行う
|
69
|
+
#
|
70
|
+
# @param [Hash] options 以下の通り
|
71
|
+
# @option options [Boolean] :direct '_' で終わるメソッドをキャッシュせずに毎回計算するか否か
|
72
|
+
# @option options [Hash{Symbol=>boolean}] :escape 毎回 method_missing を発生させるメソッドを true にする
|
73
|
+
# @option options [false, nil] :escape to_str, to_ary, to_hash のみ毎回 method_missing を発生させる
|
74
|
+
# @option options [true] :escape すべて毎回 method_missing を発生させる
|
75
|
+
#
|
76
|
+
# @return [void]
|
77
|
+
#
|
78
|
+
# @note When::TM::Calendar クラスの一部はキャッシュ使用を前提としているため :direct=>true では動作しません
|
79
|
+
#
|
80
|
+
def _setup_(options={})
|
81
|
+
@_setup_info = options
|
82
|
+
@direct = options[:direct]
|
83
|
+
case options[:escape]
|
84
|
+
when true
|
85
|
+
instance_eval %Q{
|
86
|
+
def escape(method)
|
87
|
+
true
|
88
|
+
end
|
89
|
+
}
|
90
|
+
when Hash
|
91
|
+
@escape = Escape.merge(options[:escape])
|
92
|
+
instance_eval %Q{
|
93
|
+
def escape(method)
|
94
|
+
@escape[method]
|
95
|
+
end
|
96
|
+
}
|
97
|
+
else
|
98
|
+
instance_eval %Q{
|
99
|
+
def escape(method)
|
100
|
+
Escape.key?(method)
|
101
|
+
end
|
102
|
+
}
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
# 設定情報を取得する
|
107
|
+
#
|
108
|
+
# @return [Hash] 設定情報
|
109
|
+
#
|
110
|
+
def _setup_info
|
111
|
+
@_setup_info ||= {}
|
112
|
+
end
|
113
|
+
|
114
|
+
# method_missing メソッドを forward するか否か
|
115
|
+
#
|
116
|
+
# @param [Symbol] method メソッドシンボル
|
117
|
+
#
|
118
|
+
# @return [boolean] true - しない, false/nil - する
|
119
|
+
#
|
120
|
+
def escape(method)
|
121
|
+
Escape.key?(method)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
alias :method_missing_ :method_missing
|
126
|
+
|
127
|
+
#
|
128
|
+
# 最初に発生する method_missing で、キャッシュ機能を登録する
|
129
|
+
#
|
130
|
+
# @param [Symbol] name メソッド名
|
131
|
+
# @param [Array] args メソッド引数
|
132
|
+
# @param [block] block ブロック(省略可)
|
133
|
+
#
|
134
|
+
# @return [void]
|
135
|
+
#
|
136
|
+
def method_missing(name, *args, &block)
|
137
|
+
|
138
|
+
return method_missing_(name, *args, &block) unless respond_to?("#{name}_", true)
|
139
|
+
return send("#{name}_", *args, &block) if MethodCash.direct
|
140
|
+
|
141
|
+
if ((name.to_s =~ /\A(_*)(.+?)_to_(.+)\z/) && respond_to?("#{$1}#{$3}_to_#{$2}_", true))
|
142
|
+
prefix, from, to = $~[1..3]
|
143
|
+
begin
|
144
|
+
if (@_m_cash_lock_)
|
145
|
+
return send("#{prefix}#{from}_to_#{to}_", *args, &block) unless @_m_cash_lock_.try_lock
|
146
|
+
unlock = "ensure ; @_m_cash_lock_.locked? && @_m_cash_lock_.unlock"
|
147
|
+
end
|
148
|
+
[[from, to],[to, from]].each do |pair|
|
149
|
+
a, b = pair
|
150
|
+
lock = @_m_cash_lock_ ? " return #{prefix}#{a}_to_#{b}_(*args) unless @_m_cash_lock_.try_lock" : ''
|
151
|
+
instance_eval %Q{
|
152
|
+
def #{prefix}#{a}_to_#{b}(*args)
|
153
|
+
key = _key_simplefy(args)
|
154
|
+
inv = @_m_cash_["#{prefix}#{a}_to_#{b}"][key]
|
155
|
+
return inv if inv
|
156
|
+
begin
|
157
|
+
#{lock}
|
158
|
+
inv = #{prefix}#{a}_to_#{b}_(*args)
|
159
|
+
@_m_cash_["#{prefix}#{b}_to_#{a}"][_key_simplefy(inv)] = args
|
160
|
+
@_m_cash_["#{prefix}#{a}_to_#{b}"][key] = inv
|
161
|
+
return inv
|
162
|
+
#{unlock}
|
163
|
+
end
|
164
|
+
end
|
165
|
+
}
|
166
|
+
end
|
167
|
+
key = _key_simplefy(args)
|
168
|
+
inv = send("#{prefix}#{from}_to_#{to}_", *args)
|
169
|
+
@_m_cash_ ||= {}
|
170
|
+
@_m_cash_["#{prefix}#{to}_to_#{from}"] ||= {}
|
171
|
+
@_m_cash_["#{prefix}#{from}_to_#{to}"] ||= {}
|
172
|
+
@_m_cash_["#{prefix}#{to}_to_#{from}"][_key_simplefy(inv)] = args
|
173
|
+
@_m_cash_["#{prefix}#{from}_to_#{to}"][key] = inv
|
174
|
+
return inv
|
175
|
+
ensure
|
176
|
+
@_m_cash_lock_ && @_m_cash_lock_.locked? && @_m_cash_lock_.unlock
|
177
|
+
end
|
178
|
+
|
179
|
+
else
|
180
|
+
begin
|
181
|
+
respond = respond_to?("#{name}_setup", true)
|
182
|
+
setup = respond ? "#{name}_setup(key, *args)" :
|
183
|
+
"(@_m_cash_[\"#{name}\"][key] = #{name}_(*args))"
|
184
|
+
if (@_m_cash_lock_)
|
185
|
+
return send("#{name}_", *args, &block) unless @_m_cash_lock_.try_lock
|
186
|
+
lock = " return #{name}_(*args) unless @_m_cash_lock_.try_lock"
|
187
|
+
unlock = "ensure ; @_m_cash_lock_.locked? && @_m_cash_lock_.unlock"
|
188
|
+
end
|
189
|
+
instance_eval %Q{
|
190
|
+
def #{name}(*args)
|
191
|
+
key = _key_simplefy(args)
|
192
|
+
ret = @_m_cash_["#{name}"][key]
|
193
|
+
return ret if ret
|
194
|
+
begin
|
195
|
+
#{lock}
|
196
|
+
return #{setup}
|
197
|
+
#{unlock}
|
198
|
+
end
|
199
|
+
end
|
200
|
+
}
|
201
|
+
key = _key_simplefy(args)
|
202
|
+
@_m_cash_ ||= {}
|
203
|
+
@_m_cash_["#{name}"] ||= {}
|
204
|
+
if (respond)
|
205
|
+
return send("#{name}_setup", key, *args)
|
206
|
+
else
|
207
|
+
return(@_m_cash_["#{name}"][key] ||= send("#{name}_", *args))
|
208
|
+
end
|
209
|
+
ensure
|
210
|
+
@_m_cash_lock_ && @_m_cash_lock_.locked? && @_m_cash_lock_.unlock
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
private
|
216
|
+
|
217
|
+
def _key_simplefy(args)
|
218
|
+
key = args.kind_of?(Array) ? args.dup : args
|
219
|
+
key = key[0] while key.kind_of?(Array) && key.length<=1
|
220
|
+
return key
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|