aixm 1.2.1 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/CHANGELOG.md +14 -3
  4. data/README.md +30 -2
  5. data/exe/ckmid +1 -7
  6. data/exe/mkmid +1 -7
  7. data/lib/aixm/classes.rb +2 -1
  8. data/lib/aixm/component/address.rb +12 -15
  9. data/lib/aixm/component/approach_lighting.rb +11 -16
  10. data/lib/aixm/component/fato.rb +22 -34
  11. data/lib/aixm/component/frequency.rb +10 -15
  12. data/lib/aixm/component/geometry/arc.rb +2 -3
  13. data/lib/aixm/component/geometry/border.rb +6 -10
  14. data/lib/aixm/component/geometry/circle.rb +4 -4
  15. data/lib/aixm/component/geometry/point.rb +4 -4
  16. data/lib/aixm/component/geometry/rhumb_line.rb +4 -4
  17. data/lib/aixm/component/geometry.rb +4 -4
  18. data/lib/aixm/component/helipad.rb +13 -20
  19. data/lib/aixm/component/layer.rb +6 -8
  20. data/lib/aixm/component/lighting.rb +12 -17
  21. data/lib/aixm/component/runway.rb +26 -38
  22. data/lib/aixm/component/service.rb +12 -16
  23. data/lib/aixm/component/surface.rb +8 -10
  24. data/lib/aixm/component/timesheet.rb +9 -10
  25. data/lib/aixm/component/timetable.rb +6 -7
  26. data/lib/aixm/component/vasis.rb +6 -8
  27. data/lib/aixm/component/vertical_limit.rb +8 -8
  28. data/lib/aixm/component.rb +3 -2
  29. data/lib/aixm/concerns/association.rb +381 -0
  30. data/lib/aixm/concerns/memoize.rb +107 -0
  31. data/lib/aixm/concerns/xml_builder.rb +34 -0
  32. data/lib/aixm/document.rb +52 -21
  33. data/lib/aixm/feature/airport.rb +44 -47
  34. data/lib/aixm/feature/airspace.rb +27 -34
  35. data/lib/aixm/feature/generic.rb +67 -0
  36. data/lib/aixm/feature/navigational_aid/designated_point.rb +11 -13
  37. data/lib/aixm/feature/navigational_aid/dme.rb +12 -15
  38. data/lib/aixm/feature/navigational_aid/marker.rb +12 -15
  39. data/lib/aixm/feature/navigational_aid/ndb.rb +13 -16
  40. data/lib/aixm/feature/navigational_aid/tacan.rb +15 -17
  41. data/lib/aixm/feature/navigational_aid/vor.rb +16 -19
  42. data/lib/aixm/feature/navigational_aid.rb +7 -7
  43. data/lib/aixm/feature/obstacle.rb +20 -21
  44. data/lib/aixm/feature/obstacle_group.rb +19 -20
  45. data/lib/aixm/feature/organisation.rb +11 -12
  46. data/lib/aixm/feature/unit.rb +16 -18
  47. data/lib/aixm/feature.rb +26 -7
  48. data/lib/aixm/object.rb +1 -1
  49. data/lib/aixm/refinements.rb +57 -0
  50. data/lib/aixm/version.rb +1 -1
  51. data/lib/aixm.rb +4 -3
  52. data/schemas/ofmx/0.1/OFMX-Snapshot.xsd +6 -1
  53. data.tar.gz.sig +3 -3
  54. metadata +7 -19
  55. metadata.gz.sig +0 -0
  56. data/lib/aixm/association.rb +0 -378
  57. data/lib/aixm/memoize.rb +0 -105
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aixm
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.1
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sven Schwyn
@@ -30,22 +30,8 @@ cert_chain:
30
30
  1+2Y1+i+4jd1B7qxIgOLxQTNIJiwE0sqU1itFfuesfgUACS7M0IV9u9Bp4hBGNEw
31
31
  5JcY2h7owdMxXIvgk1oakgldFJc=
32
32
  -----END CERTIFICATE-----
33
- date: 2022-04-23 00:00:00.000000000 Z
33
+ date: 2022-05-04 00:00:00.000000000 Z
34
34
  dependencies:
35
- - !ruby/object:Gem::Dependency
36
- name: builder
37
- requirement: !ruby/object:Gem::Requirement
38
- requirements:
39
- - - "~>"
40
- - !ruby/object:Gem::Version
41
- version: '3'
42
- type: :runtime
43
- prerelease: false
44
- version_requirements: !ruby/object:Gem::Requirement
45
- requirements:
46
- - - "~>"
47
- - !ruby/object:Gem::Version
48
- version: '3'
49
35
  - !ruby/object:Gem::Dependency
50
36
  name: nokogiri
51
37
  requirement: !ruby/object:Gem::Requirement
@@ -222,7 +208,6 @@ files:
222
208
  - exe/mkmid
223
209
  - lib/aixm.rb
224
210
  - lib/aixm/a.rb
225
- - lib/aixm/association.rb
226
211
  - lib/aixm/classes.rb
227
212
  - lib/aixm/component.rb
228
213
  - lib/aixm/component/address.rb
@@ -245,11 +230,14 @@ files:
245
230
  - lib/aixm/component/timetable.rb
246
231
  - lib/aixm/component/vasis.rb
247
232
  - lib/aixm/component/vertical_limit.rb
233
+ - lib/aixm/concerns/association.rb
248
234
  - lib/aixm/concerns/hash_equality.rb
249
235
  - lib/aixm/concerns/intensity.rb
250
236
  - lib/aixm/concerns/marking.rb
237
+ - lib/aixm/concerns/memoize.rb
251
238
  - lib/aixm/concerns/remarks.rb
252
239
  - lib/aixm/concerns/timetable.rb
240
+ - lib/aixm/concerns/xml_builder.rb
253
241
  - lib/aixm/config.rb
254
242
  - lib/aixm/constants.rb
255
243
  - lib/aixm/d.rb
@@ -260,6 +248,7 @@ files:
260
248
  - lib/aixm/feature.rb
261
249
  - lib/aixm/feature/airport.rb
262
250
  - lib/aixm/feature/airspace.rb
251
+ - lib/aixm/feature/generic.rb
263
252
  - lib/aixm/feature/navigational_aid.rb
264
253
  - lib/aixm/feature/navigational_aid/designated_point.rb
265
254
  - lib/aixm/feature/navigational_aid/dme.rb
@@ -271,7 +260,6 @@ files:
271
260
  - lib/aixm/feature/obstacle_group.rb
272
261
  - lib/aixm/feature/organisation.rb
273
262
  - lib/aixm/feature/unit.rb
274
- - lib/aixm/memoize.rb
275
263
  - lib/aixm/object.rb
276
264
  - lib/aixm/p.rb
277
265
  - lib/aixm/payload_hash.rb
@@ -324,7 +312,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
324
312
  - !ruby/object:Gem::Version
325
313
  version: '0'
326
314
  requirements: []
327
- rubygems_version: 3.3.12
315
+ rubygems_version: 3.3.13
328
316
  signing_key:
329
317
  specification_version: 4
330
318
  summary: Builder for AIXM/OFMX aeronautical information
metadata.gz.sig CHANGED
Binary file
@@ -1,378 +0,0 @@
1
- using AIXM::Refinements
2
-
3
- module AIXM
4
-
5
- # Associate features and components with a minimalistic implementation of
6
- # +has_many+, +has_one+ and +belongs_to+ associations.
7
- #
8
- # When adding or assigning an object on the associator (where the +has_many+
9
- # or +has_one+ declaration is made), the object is verified and must be an
10
- # instance of the declared class or a superclass thereof.
11
- #
12
- # When assigning an object on the associated (where the +belongs_to+
13
- # declaration is made), the object is not verified. However, since the actual
14
- # assignment is always delegated to the associator, unacceptable objects will
15
- # raise errors.
16
- #
17
- # @example Simple +has_many+ association
18
- # class Blog
19
- # has_many :posts # :post has to be a key in AIXM::CLASSES
20
- # end
21
- # class Post
22
- # belongs_to :blog
23
- # end
24
- # blog, post = Blog.new, Post.new
25
- # # --either--
26
- # blog.add_post(post) # => Blog
27
- # blog.posts.count # => 1
28
- # blog.posts.first == post # => true
29
- # post.blog == blog # => true
30
- # blog.remove_post(post) # => Blog
31
- # blog.posts.count # => 0
32
- # # --or--
33
- # post.blog = blog # => Blog
34
- # blog.posts.count # => 1
35
- # blog.posts.first == post # => true
36
- # post.blog == blog # => true
37
- # post.blog = nil # => nil
38
- # blog.posts.count # => 0
39
- # # --or--
40
- # post_2 = Post.new
41
- # blog.add_posts([post, post_2])
42
- # blog.posts.count # => 2
43
- # blog.posts == [post, post_2] # => true
44
- # blog.remove_posts([post_2, post])
45
- # blog.posts.count # => 0
46
- #
47
- # @example Simple +has_one+ association
48
- # class Blog
49
- # has_one :posts # :post has to be a key in AIXM::CLASSES
50
- # end
51
- # class Post
52
- # belongs_to :blog
53
- # end
54
- # blog, post = Blog.new, Post.new
55
- # # --either--
56
- # blog.post = post # => Post (standard assignment)
57
- # blog.add_post(post) # => Blog (alternative for chaining)
58
- # blog.post == post # => true
59
- # post.blog == blog # => true
60
- # blog.post = nil # => nil
61
- # blog.post # => nil
62
- # post.blog # => nil
63
- # # --or--
64
- # post.blog = blog # => Blog (standard assignment)
65
- # post.add_blog(blog) # => Post (alternative for chaining)
66
- # post.blog == blog # => true
67
- # blog.post == post # => true
68
- # post.blog = nil # => nil
69
- # post.blog # => nil
70
- # blog.post # => nil
71
- #
72
- # @example Association with readonly +belongs_to+ (idem for +has_one+)
73
- # class Blog
74
- # has_many :posts # :post has to be a key in AIXM::CLASSES
75
- # end
76
- # class Post
77
- # belongs_to :blog, readonly: true
78
- # end
79
- # blog, post = Blog.new, Post.new
80
- # post.blog = blog # => NoMethodError
81
- #
82
- # @example Association with explicit class (idem for +has_one+)
83
- # class Blog
84
- # include AIXM::Association
85
- # has_many :posts, accept: 'Picture'
86
- # end
87
- # class Picture
88
- # include AIXM::Association
89
- # belongs_to :blog
90
- # end
91
- # blog, picture = Blog.new, Picture.new
92
- # blog.add_post(picture)
93
- # blog.posts.first == picture # => true
94
- #
95
- # @example Polymorphic associator (idem for +has_one+)
96
- # class Blog
97
- # has_many :posts, as: :postable
98
- # end
99
- # class Feed
100
- # has_many :posts, as: :postable
101
- # end
102
- # class Post
103
- # belongs_to :postable
104
- # end
105
- # blog, feed, post_1, post_2, post_3 = Blog.new, Feed.new, Post.new, Post.new, Post.new
106
- # blog.add_post(post_1)
107
- # post_1.postable == blog # => true
108
- # feed.add_post(post_2)
109
- # post_2.postable == feed # => true
110
- # post_3.postable = blog # => NoMethodError
111
- #
112
- # @example Polymorphic associated (idem for +has_one+)
113
- # class Blog
114
- # include AIXM::Association
115
- # has_many :items, accept: ['Post', :picture]
116
- # end
117
- # class Post
118
- # include AIXM::Association
119
- # belongs_to :blog, as: :item
120
- # end
121
- # class Picture
122
- # include AIXM::Association
123
- # belongs_to :blog, as: :item
124
- # end
125
- # blog, post, picture = Blog.new, Post.new, Picture.new
126
- # blog.add_item(post)
127
- # blog.add_item(picture)
128
- # blog.items.count # => 2
129
- # blog.items.first == post # => true
130
- # blog.items.last == picture # => true
131
- # post.blog == blog # => true
132
- # picture.blog == blog # => true
133
- #
134
- # @example Add method which enriches passed associated object (+has_many+ only)
135
- # class Blog
136
- # has_many :posts do |post, related_to: nil| # this defines the signature of add_post
137
- # post.related_to = related_to || @posts.last # executes in the context of the current blog
138
- # end
139
- # end
140
- # class Post
141
- # belongs_to :blog
142
- # attr_accessor :related_to
143
- # end
144
- # blog, post_1, post_2, post_3 = Blog.new, Post.new, Post.new, Post.new
145
- # blog.add_post(post_1)
146
- # post_1.related_to # => nil
147
- # blog.add_post(post_2)
148
- # post_2.related_to == post_1 # => true
149
- # blog.add_post(post_3, related_to: post_1)
150
- # post_3.related_to == post_1 # => true
151
- #
152
- # @example Add method which builds and yields new associated object (+has_many+ only)
153
- # class Blog
154
- # include AIXM::Association
155
- # has_many :posts do |post, title:| end
156
- # end
157
- # class Post
158
- # include AIXM::Association
159
- # belongs_to :blog
160
- # attr_accessor :title, :text
161
- # def initialize(title:) # same signature as "has_many" block above
162
- # @title = title
163
- # end
164
- # end
165
- # blog = Blog.new
166
- # blog.add_post(title: "title") do |post| # note that no post instance is passed
167
- # post.text = "text"
168
- # end
169
- # blog.posts.first.title # => "title"
170
- # blog.posts.first.text # => "text"
171
- module Association
172
- module ClassMethods
173
- attr_reader :has_many_attributes, :has_one_attributes, :belongs_to_attributes
174
-
175
- def has_many(attribute, as: nil, accept: nil, &association_block)
176
- association = attribute.to_s.inflect(:singularize)
177
- inversion = as || self.to_s.inflect(:demodulize, :tableize, :singularize)
178
- class_names = [accept || association].flatten.map { AIXM::CLASSES[_1.to_sym] || _1 }
179
- (@has_many_attributes ||= []) << attribute
180
- # features
181
- define_method(attribute) do
182
- instance_variable_get(:"@#{attribute}") || AIXM::Association::Array.new
183
- end
184
- # add_feature
185
- define_method(:"add_#{association}") do |object=nil, **options, &add_block|
186
- unless object
187
- fail(ArgumentError, "must pass object to add") if class_names.count > 1
188
- object = class_names.first.to_class.new(**options)
189
- add_block.call(object) if add_block
190
- end
191
- instance_exec(object, **options, &association_block) if association_block
192
- fail(ArgumentError, "#{object.__class__} not allowed") unless class_names.any? { |c| object.is_a?(c.to_class) }
193
- instance_eval("@#{attribute} ||= AIXM::Association::Array.new")
194
- send(attribute).send(:push, object)
195
- object.instance_variable_set(:"@#{inversion}", self)
196
- self
197
- end
198
- # add_features
199
- define_method(:"add_#{attribute}") do |objects=[], **options, &add_block|
200
- objects.each { send(:"add_#{association}", _1, **options, &add_block) }
201
- self
202
- end
203
- # remove_feature
204
- define_method(:"remove_#{association}") do |object|
205
- send(attribute).send(:delete, object)
206
- object.instance_variable_set(:"@#{inversion}", nil)
207
- self
208
- end
209
- # remove_features
210
- define_method(:"remove_#{attribute}") do |objects=[]|
211
- objects.each { send(:"remove_#{association}", _1) }
212
- self
213
- end
214
- end
215
-
216
- def has_one(attribute, as: nil, accept: nil, allow_nil: false)
217
- association = attribute.to_s
218
- inversion = (as || self.to_s.inflect(:demodulize, :tableize, :singularize)).to_s
219
- class_names = [accept || association].flatten.map { AIXM::CLASSES[_1.to_sym] || _1 }
220
- class_names << 'NilClass' if allow_nil
221
- (@has_one_attributes ||= []) << attribute
222
- # feature
223
- attr_reader attribute
224
- # feature=
225
- define_method(:"#{association}=") do |object|
226
- fail(ArgumentError, "#{object.__class__} not allowed") unless class_names.any? { |c| object.is_a?(c.to_class) }
227
- instance_variable_get(:"@#{attribute}")&.instance_variable_set(:"@#{inversion}", nil)
228
- instance_variable_set(:"@#{attribute}", object)
229
- object&.instance_variable_set(:"@#{inversion}", self)
230
- object
231
- end
232
- # add_feature
233
- define_method(:"add_#{association}") do |object|
234
- send("#{association}=", object)
235
- self
236
- end
237
- # remove_feature
238
- define_method(:"remove_#{association}") do |_|
239
- send(:"#{association}=", nil)
240
- self
241
- end
242
- end
243
-
244
- def belongs_to(attribute, as: nil, readonly: false)
245
- association = self.to_s.inflect(:demodulize, :tableize, :singularize)
246
- inversion = (as || association).to_s
247
- (@belongs_to_attributes ||= []) << attribute
248
- # feature
249
- attr_reader attribute
250
- unless readonly
251
- # feature=
252
- define_method(:"#{attribute}=") do |object|
253
- instance_variable_get(:"@#{attribute}")&.send(:"remove_#{inversion}", self)
254
- object&.send(:"add_#{inversion}", self)
255
- object
256
- end
257
- # add_feature
258
- define_method(:"add_#{attribute}") do |object|
259
- send("#{attribute}=", object)
260
- self
261
- end
262
- end
263
- end
264
- end
265
-
266
- def self.included(base)
267
- base.extend(ClassMethods)
268
- end
269
-
270
- class Array < ::Array
271
- private :<<, :push, :append, :unshift, :prepend
272
- private :delete, :pop, :shift
273
-
274
- # Find objects of the given class and optionally with the given
275
- # attribute values on a has_many association.
276
- #
277
- # The class can either be declared by passing the class itself or by
278
- # passing a shortcut symbol as listed in +AIXM::CLASSES+.
279
- #
280
- # @example
281
- # class Blog
282
- # include AIXM::Association
283
- # has_many :items, accept: %i(post picture)
284
- # end
285
- # class Post
286
- # include AIXM::Association
287
- # belongs_to :blog, as: :item
288
- # attr_accessor :title
289
- # end
290
- # class Picture
291
- # include AIXM::Association
292
- # belongs_to :blog, as: :item
293
- # end
294
- # blog, post, picture = Blog.new, Post.new, Picture.new
295
- # post.title = "title"
296
- # blog.add_item(post)
297
- # blog.add_item(picture)
298
- # blog.items.find_by(:post) == [post] # => true
299
- # blog.items.find_by(Post) == [post] # => true
300
- # blog.items.find_by(:post, title: "title") == [post] # => true
301
- # blog.items.find_by(Object) == [post, picture] # => true
302
- #
303
- # @param klass [Class, Symbol] class (e.g. AIXM::Feature::Airport,
304
- # AIXM::Feature::NavigationalAid::VOR) or shortcut symbol (e.g.
305
- # :airport or :vor) as listed in AIXM::CLASSES
306
- # @param attributes [Hash] search attributes by their values
307
- # @return [AIXM::Association::Array]
308
- def find_by(klass, attributes={})
309
- if klass.is_a? Symbol
310
- klass = AIXM::CLASSES[klass]&.to_class || fail(ArgumentError, "unknown class shortcut `#{klass}'")
311
- end
312
- self.class.new(
313
- select do |element|
314
- if element.kind_of? klass
315
- attributes.all? { |a, v| element.send(a) == v }
316
- end
317
- end
318
- )
319
- end
320
-
321
- # Find equal objects on a has_many association.
322
- #
323
- # This may seem redundant at first, but keep in mind that two instances
324
- # of +AIXM::CLASSES+ which implement `#to_uid` are considered equal if
325
- # they are instances of the same class and both their UIDs as calculated
326
- # by `#to_uid` are equal. Attributes which are not part of the `#to_uid`
327
- # calculation are irrelevant!
328
- #
329
- # @example
330
- # class Blog
331
- # include AIXM::Association
332
- # has_many :items, accept: %i(post picture)
333
- # end
334
- # class Post
335
- # include AIXM::Association
336
- # belongs_to :blog, as: :item
337
- # attr_accessor :title
338
- # end
339
- # blog, post = Blog.new, Post.new
340
- # blog.add_item(post)
341
- # blog.items.find(post) == [post] # => true
342
- #
343
- # @param object [Object] instance of class listed in AIXM::CLASSES
344
- # @return [AIXM::Association::Array]
345
- def find(object)
346
- klass = object.__class__
347
- self.class.new(
348
- select do |element|
349
- element.kind_of?(klass) && element == object
350
- end
351
- )
352
- end
353
-
354
- # Find equal or identical duplicates on a has_many association.
355
- #
356
- # @example
357
- # class Blog
358
- # include AIXM::Association
359
- # has_many :posts
360
- # end
361
- # class Post
362
- # include AIXM::Association
363
- # belongs_to :blog
364
- # end
365
- # blog, post = Blog.new, Post.new
366
- # duplicate_post = post.dup
367
- # blog.add_posts([post, duplicate_post])
368
- # blog.posts.duplicates # => [[post, duplicate_post]]
369
- #
370
- # @return [Array<Array<AIXM::Feature>>]
371
- def duplicates
372
- AIXM::Memoize.method :to_uid do
373
- group_by(&:to_uid).select { |_, a| a.count > 1 }.map(&:last)
374
- end
375
- end
376
- end
377
- end
378
- end
data/lib/aixm/memoize.rb DELETED
@@ -1,105 +0,0 @@
1
- module AIXM
2
-
3
- # Memoize the return value of a specific method across multiple instances for
4
- # the duration of a block.
5
- #
6
- # The method signature is taken into account, therefore calls of the same
7
- # method with different positional and/or keyword arguments are cached
8
- # independently. On the other hand, when calling the method with a block,
9
- # no memoization is performed at all.
10
- #
11
- # Nested memoization of the same method is allowed and won't reset the
12
- # memoization cache.
13
- #
14
- # @example
15
- # class Either
16
- # include AIXM::Memoize
17
- #
18
- # def either(argument=nil, keyword: nil, &block)
19
- # $entropy || argument || keyword || (block.call if block)
20
- # end
21
- # memoize :either
22
- # end
23
- #
24
- # a, b, c = Either.new, Either.new, Either.new
25
- #
26
- # # No memoization before the block
27
- # $entropy = nil
28
- # a.either(1) # => 1
29
- # b.either(keyword: 2) # => 2
30
- # c.either { 3 } # => 3
31
- # $entropy = :not_nil
32
- # a.either(1) # => :not_nil
33
- # b.either(keyword: 2) # => :not_nil
34
- # c.either { 3 } # => :not_nil
35
- #
36
- # # Memoization inside the block
37
- # AIXM::Memoize.method :either do
38
- # $entropy = nil
39
- # a.either(1) # => 1
40
- # b.either(keyword: 2) # => 2
41
- # c.either { 3 } # => 3
42
- # $entropy = :not_nil
43
- # a.either(1) # => 1 (memoized)
44
- # b.either(keyword: 2) # => 2 (memoized)
45
- # c.either { 3 } # => :not_nil (cannot be memoized)
46
- # end
47
- #
48
- # # No memoization after the block
49
- # $entropy = nil
50
- # a.either(1) # => 1
51
- # $entropy = :not_nil
52
- # a.either(1) # => :not_nil
53
- module Memoize
54
- module ClassMethods
55
- def memoize(method)
56
- unmemoized_method = :"unmemoized_#{method}"
57
- alias_method unmemoized_method, method
58
- define_method method do |*args, **kargs, &block|
59
- if block || !AIXM::Memoize.cache.has_key?(method)
60
- send(unmemoized_method, *args, **kargs, &block)
61
- else
62
- cache = AIXM::Memoize.cache[method]
63
- id = object_id.hash ^ args.hash ^ kargs.hash
64
- if cache.has_key?(id)
65
- cache[id]
66
- else
67
- cache[id] = send(unmemoized_method, *args, **kargs)
68
- end
69
- end
70
- end
71
- end
72
- end
73
-
74
- class << self
75
- attr_reader :cache
76
-
77
- def included(base)
78
- base.extend(ClassMethods)
79
- @cache = {}
80
- end
81
-
82
- def method(method, &block) # TODO: [ruby-3.1] use anonymous block "&" on this and next line
83
- send(:"call_with#{:out if cached?(method)}_cache", method, &block)
84
- end
85
-
86
- private
87
-
88
- def cached?(method)
89
- cache.has_key?(method)
90
- end
91
-
92
- def call_without_cache(method)
93
- yield
94
- end
95
-
96
- def call_with_cache(method)
97
- cache[method] = {}
98
- yield
99
- ensure
100
- cache.delete(method)
101
- end
102
- end
103
-
104
- end
105
- end