when_exe 0.4.2 → 0.5.0

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.
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