when_exe 0.4.2 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (144) hide show
  1. checksums.yaml +5 -5
  2. data/LICENSE.ja.txt +8 -21
  3. data/LICENSE.txt +5 -27
  4. data/README.md +25 -79
  5. data/bin/.pryrc +9 -0
  6. data/bin/make_ttl.rb +3 -2
  7. data/bin/make_ttl.rb.config +3 -3
  8. data/lib/when_exe.rb +101 -5
  9. data/lib/when_exe/basictypes.rb +47 -16
  10. data/lib/when_exe/calendarnote.rb +27 -18
  11. data/lib/when_exe/calendartypes.rb +12 -50
  12. data/lib/when_exe/coordinates.rb +37 -391
  13. data/lib/when_exe/ephemeris.rb +53 -14
  14. data/lib/when_exe/ephemeris/eclipse.rb +8 -8
  15. data/lib/when_exe/ephemeris/moon.rb +333 -333
  16. data/lib/when_exe/ephemeris/notes.rb +29 -17
  17. data/lib/when_exe/ephemeris/phase_table.rb +825 -0
  18. data/lib/when_exe/ephemeris/term_table.rb +603 -0
  19. data/lib/when_exe/events.rb +1888 -0
  20. data/lib/when_exe/google_api.rb +26 -31
  21. data/lib/when_exe/icalendar.rb +129 -12
  22. data/lib/when_exe/inspect.rb +5 -5
  23. data/lib/when_exe/linkeddata.rb +43 -23
  24. data/lib/when_exe/locales/akt.rb +63 -0
  25. data/lib/when_exe/locales/encoding_conversion.rb +134 -134
  26. data/lib/when_exe/locales/iast.rb +90 -90
  27. data/lib/when_exe/locales/locale.rb +88 -18
  28. data/lib/when_exe/locales/transliteration_table.rb +62 -62
  29. data/lib/when_exe/mini_application.rb +14 -8
  30. data/lib/when_exe/namespace.rb +42 -0
  31. data/lib/when_exe/parts/enumerator.rb +16 -5
  32. data/lib/when_exe/parts/geometric_complex.rb +52 -2
  33. data/lib/when_exe/parts/method_cash.rb +229 -224
  34. data/lib/when_exe/parts/resource.rb +65 -35
  35. data/lib/when_exe/parts/timezone.rb +25 -34
  36. data/lib/when_exe/region/balinese.rb +5 -3
  37. data/lib/when_exe/region/chinese.rb +39 -11
  38. data/lib/when_exe/region/chinese/calendars.rb +1016 -1016
  39. data/lib/when_exe/region/chinese/epochs.rb +7 -7
  40. data/lib/when_exe/region/chinese/notes.rb +3 -3
  41. data/lib/when_exe/region/chinese/twins.rb +134 -11
  42. data/lib/when_exe/region/dee.rb +4 -4
  43. data/lib/when_exe/region/discordian.rb +1 -1
  44. data/lib/when_exe/region/geologicalage.rb +139 -128
  45. data/lib/when_exe/region/hanke_henry.rb +4 -4
  46. data/lib/when_exe/region/indian.rb +77 -8
  47. data/lib/when_exe/region/international_fixed.rb +3 -3
  48. data/lib/when_exe/region/islamic.rb +1 -1
  49. data/lib/when_exe/region/japanese.rb +12 -8
  50. data/lib/when_exe/region/japanese/calendars.rb +397 -397
  51. data/lib/when_exe/region/japanese/eclipses.rb +1194 -1194
  52. data/lib/when_exe/region/japanese/epochs.rb +8 -4
  53. data/lib/when_exe/region/japanese/location.rb +93 -0
  54. data/lib/when_exe/region/japanese/nihon_shoki.rb +70 -70
  55. data/lib/when_exe/region/japanese/notes.rb +57 -18
  56. data/lib/when_exe/region/japanese/residues.rb +33 -11
  57. data/lib/when_exe/region/japanese/twins.rb +27 -14
  58. data/lib/when_exe/region/japanese/weeks.rb +7 -7
  59. data/lib/when_exe/region/korean.rb +384 -384
  60. data/lib/when_exe/region/location.rb +40 -0
  61. data/lib/when_exe/region/martian.rb +1 -1
  62. data/lib/when_exe/region/mayan.rb +2 -2
  63. data/lib/when_exe/region/roman.rb +2 -2
  64. data/lib/when_exe/region/ryukyu.rb +101 -101
  65. data/lib/when_exe/region/saudi_arabian.rb +57 -0
  66. data/lib/when_exe/region/shire.rb +1 -1
  67. data/lib/when_exe/region/world.rb +3 -3
  68. data/lib/when_exe/region/zoroastrian.rb +1 -1
  69. data/lib/when_exe/spatial.rb +611 -0
  70. data/lib/when_exe/timestandard.rb +9 -7
  71. data/lib/when_exe/tmobjects.rb +34 -2
  72. data/lib/when_exe/tmposition.rb +225 -1322
  73. data/lib/when_exe/tmptypes.rb +1279 -0
  74. data/lib/when_exe/tmreference.rb +42 -7
  75. data/lib/when_exe/version.rb +3 -3
  76. data/test/events/example-datasets +6 -0
  77. data/test/events/history-dataset.csv +22 -0
  78. data/test/events/japanese-holiday-index.csv +28 -0
  79. data/test/events/japanese-holiday.csv +94 -0
  80. data/test/events/japanese-holiday.ttl +948 -0
  81. data/test/events/make_events_ttl.rb +18 -0
  82. data/test/events/mori_wikichoshi.csv +14 -0
  83. data/test/events/ndl_koyomi.csv +220 -0
  84. data/test/events/ndl_koyomi_index.csv +44 -0
  85. data/test/events/primeminister-dataset.csv +19 -0
  86. data/test/events/shogun-dataset.csv +22 -0
  87. data/test/events/test-history-dataset-edge-sparql.csv +26 -0
  88. data/test/events/test-history-dataset-edge.csv +27 -0
  89. data/test/events/test-history-dataset-sparql.csv +22 -0
  90. data/test/events/test-history-dataset.csv +23 -0
  91. data/test/events/test-history-events-edge.ttl +89 -0
  92. data/test/events/test-history-events.csv +6 -0
  93. data/test/examples/JapanHolidays.ics +2 -2
  94. data/test/examples/JapanHolidaysRFC6350.ics +3 -3
  95. data/test/examples/Residue.m17n +2 -2
  96. data/test/examples/Spatial.m17n +3 -3
  97. data/test/examples/Terms.m17n +3 -3
  98. data/test/scripts/8.ext.rb +6 -6
  99. data/test/scripts/8.rb +6 -6
  100. data/test/scripts/geometric_complex.rb +41 -41
  101. data/test/scripts/korea.rb +59 -59
  102. data/test/scripts/thai.rb +36 -36
  103. data/test/test.rb +6 -0
  104. data/test/test/basictypes.rb +431 -431
  105. data/test/test/calendarnote.rb +86 -86
  106. data/test/test/calendartypes.rb +97 -97
  107. data/test/test/coordinates.rb +399 -397
  108. data/test/test/ephemeris.rb +115 -115
  109. data/test/test/ephemeris/moon.rb +14 -14
  110. data/test/test/ephemeris/planets.rb +14 -14
  111. data/test/test/ephemeris/sun.rb +14 -14
  112. data/test/test/events.rb +32 -0
  113. data/test/test/google_api.rb +45 -32
  114. data/test/test/inspect.rb +153 -153
  115. data/test/test/parts.rb +488 -488
  116. data/test/test/region/armenian.rb +20 -20
  117. data/test/test/region/bahai.rb +58 -58
  118. data/test/test/region/balinese.rb +34 -34
  119. data/test/test/region/chinese.rb +229 -229
  120. data/test/test/region/christian.rb +226 -226
  121. data/test/test/region/coptic.rb +27 -27
  122. data/test/test/region/discordian.rb +20 -20
  123. data/test/test/region/french.rb +33 -33
  124. data/test/test/region/geologicalage.rb +17 -17
  125. data/test/test/region/indian.rb +14 -1
  126. data/test/test/region/iran.rb +54 -54
  127. data/test/test/region/islamic.rb +64 -54
  128. data/test/test/region/japanese.rb +281 -261
  129. data/test/test/region/jewish.rb +63 -63
  130. data/test/test/region/m17n.rb +21 -21
  131. data/test/test/region/mayan.rb +17 -16
  132. data/test/test/region/reforms.rb +2 -2
  133. data/test/test/region/residue.rb +7 -7
  134. data/test/test/region/shire.rb +58 -58
  135. data/test/test/region/swedish.rb +45 -45
  136. data/test/test/region/thai.rb +116 -116
  137. data/test/test/region/tibetan.rb +30 -30
  138. data/test/test/region/vietnamese.rb +102 -102
  139. data/test/test/region/zoroastrian.rb +58 -58
  140. data/test/test/timestandard.rb +81 -81
  141. data/test/test/tmobjects.rb +402 -402
  142. data/test/test/tmposition.rb +66 -4
  143. data/test/test/tmreference.rb +157 -157
  144. metadata +36 -93
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  =begin
3
- Copyright (C) 2011-2015 Takashi SUGA
3
+ Copyright (C) 2011-2021 Takashi SUGA
4
4
 
5
5
  You may use and/or modify this file according to the license described in the LICENSE.txt file included in this archive.
6
6
  =end
@@ -224,6 +224,56 @@ module When::Parts
224
224
  end
225
225
  end
226
226
 
227
+ # オブジェクト変換オプションの遅延適用
228
+ #
229
+ # @param [Hash] options 以下の通り
230
+ # @option options [Hash<Integrt=>When::Coordinates::Residue>] :residue
231
+ # @option options [When::TM::Clock] :clock
232
+ # @option options [Array <When::TM::Calendar>] :frame
233
+ #
234
+ # @return [When::Parts::GeometricComplex]
235
+ #
236
+ def apply_delayed_options(options)
237
+ last_node = nil
238
+ self.class.new(@node.map {|node|
239
+ point, flag, range = node
240
+ if range && last_node
241
+ [last_node + range, flag, range]
242
+ else
243
+ last_node = point.apply_delayed_options(options)
244
+ [last_node, flag]
245
+ end
246
+ }, @reverse)
247
+ end
248
+
249
+ # 平行移動(加算)
250
+ #
251
+ # @param [When::TM::Duration] duration
252
+ #
253
+ # @return [When::Parts::GeometricComplex]
254
+ #
255
+ def +(duration)
256
+ self.class.new(@node.map {|node|
257
+ new_node = node.dup
258
+ new_node[0] += duration
259
+ new_node
260
+ }, @reverse)
261
+ end
262
+
263
+ # 平行移動(減算)
264
+ #
265
+ # @param [When::TM::Duration] duration
266
+ #
267
+ # @return [When::Parts::GeometricComplex]
268
+ #
269
+ def -(duration)
270
+ self.class.new(@node.map {|node|
271
+ new_node = node.dup
272
+ new_node[0] -= duration
273
+ new_node
274
+ }, @reverse)
275
+ end
276
+
227
277
  # オブジェクトの生成
228
278
  #
229
279
  # @overload initialize(range, reverse=false)
@@ -288,7 +338,7 @@ module When::Parts
288
338
  first = [first, true]
289
339
  case last
290
340
  when Comparable ; last = [last, false]
291
- when When::TM::Duration ; last = [first[0] + last, false]
341
+ when When::TM::Duration ; last = [first[0] + last, false, last]
292
342
  when nil ; last = first
293
343
  else ; raise TypeError, "Irregal GeometricComplex Type for last element: #{last.class}"
294
344
  end
@@ -1,224 +1,229 @@
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
+ rescue ThreadError
165
+ end
166
+ }
167
+ end
168
+ key = _key_simplefy(args)
169
+ inv = send("#{prefix}#{from}_to_#{to}_", *args)
170
+ @_m_cash_ ||= Hash.new {|hash,key| hash[key]={}}
171
+ @_m_cash_["#{prefix}#{to}_to_#{from}"][_key_simplefy(inv)] = args
172
+ @_m_cash_["#{prefix}#{from}_to_#{to}"][key] = inv
173
+ return inv
174
+ ensure
175
+ begin
176
+ @_m_cash_lock_ && @_m_cash_lock_.locked? && @_m_cash_lock_.unlock
177
+ rescue ThreadError
178
+ end
179
+ end
180
+
181
+ else
182
+ begin
183
+ respond = respond_to?("#{name}_setup", true)
184
+ setup = respond ? "#{name}_setup(key, *args)" :
185
+ "(@_m_cash_[\"#{name}\"][key] = #{name}_(*args))"
186
+ if @_m_cash_lock_
187
+ return send("#{name}_", *args, &block) unless @_m_cash_lock_.try_lock
188
+ lock = " return #{name}_(*args) unless @_m_cash_lock_.try_lock"
189
+ unlock = "ensure ; @_m_cash_lock_.locked? && @_m_cash_lock_.unlock"
190
+ end
191
+ instance_eval %Q{
192
+ def #{name}(*args)
193
+ key = _key_simplefy(args)
194
+ ret = @_m_cash_["#{name}"][key]
195
+ return ret if ret
196
+ begin
197
+ #{lock}
198
+ return #{setup}
199
+ #{unlock}
200
+ end
201
+ rescue ThreadError
202
+ end
203
+ }
204
+ key = _key_simplefy(args)
205
+ @_m_cash_ ||= Hash.new {|hash,key| hash[key]={}}
206
+ if respond
207
+ return send("#{name}_setup", key, *args)
208
+ else
209
+ return(@_m_cash_["#{name}"][key] ||= send("#{name}_", *args))
210
+ end
211
+ ensure
212
+ begin
213
+ @_m_cash_lock_ && @_m_cash_lock_.locked? && @_m_cash_lock_.unlock
214
+ rescue ThreadError
215
+ end
216
+ end
217
+ end
218
+ end
219
+
220
+ private
221
+
222
+ def _key_simplefy(args)
223
+ key = args.kind_of?(Array) ? args.dup : args
224
+ key = key[0] while key.kind_of?(Array) && key.length<=1
225
+ return key
226
+ end
227
+ end
228
+ end
229
+ end