og 0.7.0 → 0.8.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 (51) hide show
  1. data/AUTHORS +14 -4
  2. data/ChangeLog +192 -1
  3. data/README.og +2 -1
  4. data/RELEASES.og +35 -0
  5. data/Rakefile +1 -1
  6. data/examples/og/mock_example.rb +6 -9
  7. data/examples/og/mysql_to_psql.rb +100 -0
  8. data/examples/og/run.rb +8 -17
  9. data/lib/glue/array.rb +1 -1
  10. data/lib/glue/attribute.rb +86 -0
  11. data/lib/glue/cache.rb +1 -1
  12. data/lib/glue/hash.rb +1 -1
  13. data/lib/glue/inflector.rb +1 -1
  14. data/lib/glue/logger.rb +118 -18
  15. data/lib/glue/mixins.rb +1 -1
  16. data/lib/glue/number.rb +1 -1
  17. data/lib/glue/pool.rb +1 -1
  18. data/lib/glue/property.rb +48 -31
  19. data/lib/glue/string.rb +1 -1
  20. data/lib/glue/time.rb +2 -2
  21. data/lib/glue/validation.rb +400 -0
  22. data/lib/glue.rb +7 -8
  23. data/lib/og/backend.rb +47 -46
  24. data/lib/og/backends/mysql.rb +64 -63
  25. data/lib/og/backends/psql.rb +73 -72
  26. data/lib/og/connection.rb +7 -8
  27. data/lib/og/enchant.rb +80 -0
  28. data/lib/og/meta.rb +21 -21
  29. data/lib/og/mock.rb +31 -88
  30. data/lib/og/version.rb +6 -5
  31. data/lib/og.rb +95 -129
  32. data/test/tc_og.rb +3 -3
  33. data/vendor/extensions/_base.rb +153 -0
  34. data/vendor/extensions/_template.rb +36 -0
  35. data/vendor/extensions/all.rb +21 -0
  36. data/vendor/extensions/array.rb +68 -0
  37. data/vendor/extensions/binding.rb +224 -0
  38. data/vendor/extensions/class.rb +50 -0
  39. data/vendor/extensions/continuation.rb +71 -0
  40. data/vendor/extensions/enumerable.rb +250 -0
  41. data/vendor/extensions/hash.rb +23 -0
  42. data/vendor/extensions/io.rb +58 -0
  43. data/vendor/extensions/kernel.rb +42 -0
  44. data/vendor/extensions/module.rb +114 -0
  45. data/vendor/extensions/numeric.rb +230 -0
  46. data/vendor/extensions/object.rb +164 -0
  47. data/vendor/extensions/ostruct.rb +41 -0
  48. data/vendor/extensions/string.rb +316 -0
  49. data/vendor/extensions/symbol.rb +28 -0
  50. metadata +24 -4
  51. data/lib/glue/property.rb.old +0 -307
@@ -0,0 +1,316 @@
1
+ #!/usr/local/bin/ruby -w
2
+
3
+ #
4
+ # == extensions/string.rb
5
+ #
6
+ # Adds methods to the builtin String class.
7
+ #
8
+
9
+ require "extensions/_base"
10
+
11
+
12
+ ExtensionsProject.implement(String, :leftmost_indent) do
13
+ class String
14
+ #
15
+ # Returns the size of the smallest indent of any line in the string.
16
+ # Emits a warning if tabs are found, and if <tt>$VERBOSE</tt> is on.
17
+ # You can use #expand_tabs to avoid this. This method is primarily intended
18
+ # for use by #tabto and is not likely to be all that useful in its own
19
+ # right.
20
+ #
21
+ def leftmost_indent
22
+ tabs_found = false
23
+ scan(/^([ \t]*)\S/).flatten.map { |ws|
24
+ tabs_found = true if ws =~ /\t/
25
+ ws.size
26
+ }.compact.min
27
+ ensure
28
+ if tabs_found and $VERBOSE
29
+ $stderr.puts %{
30
+ String#leftmost_indent: warning: tabs treated as spaces
31
+ (value: #{self.inspect[0..30]}...")
32
+ }.strip
33
+ end
34
+ end
35
+ protected :leftmost_indent
36
+ end
37
+ end
38
+
39
+
40
+ ExtensionsProject.implement(String, :expand_tabs) do
41
+ class String
42
+ #
43
+ # Expands tabs to +n+ spaces. Non-destructive. If +n+ is 0, then tabs are
44
+ # simply removed. Raises an exception if +n+ is negative.
45
+ #
46
+ #--
47
+ # Thanks to GGaramuno for a more efficient algorithm. Very nice.
48
+ def expand_tabs(n=8)
49
+ n = n.to_int
50
+ raise ArgumentError, "n must be >= 0" if n < 0
51
+ return gsub(/\t/, "") if n == 0
52
+ return gsub(/\t/, " ") if n == 1
53
+ str = self.dup
54
+ while
55
+ str.gsub!(/^([^\t\n]*)(\t+)/) { |f|
56
+ val = ( n * $2.size - ($1.size % n) )
57
+ $1 << (' ' * val)
58
+ }
59
+ end
60
+ str
61
+ end
62
+ end
63
+ end
64
+
65
+
66
+ ExtensionsProject.implement(String, :indent) do
67
+ class String
68
+ #
69
+ # Indents the string +n+ spaces.
70
+ #
71
+ def indent(n)
72
+ n = n.to_int
73
+ return outdent(-n) if n < 0
74
+ gsub(/^/, " "*n)
75
+ end
76
+ end
77
+ end
78
+
79
+
80
+ ExtensionsProject.implement(String, :outdent) do
81
+ class String
82
+ #
83
+ # Outdents the string +n+ spaces. Initial tabs will cause problems and
84
+ # cause a warning to be emitted (if warnings are on). Relative indendation
85
+ # is always preserved. Once the block hits the beginning of the line,
86
+ # that's it. In the following example, <tt>.</tt> represents space from the
87
+ # beginning of the line.
88
+ #
89
+ # str = %{
90
+ # ..One
91
+ # ....Two
92
+ # }.outdent(4)
93
+ #
94
+ # is
95
+ #
96
+ # One
97
+ # ..Two
98
+ #
99
+ def outdent(n)
100
+ n = n.to_int
101
+ return indent(-n) if n < 0
102
+ tabto(leftmost_indent - n)
103
+ end
104
+ end
105
+ end
106
+
107
+
108
+ ExtensionsProject.implement(String, :tabto) do
109
+ class String
110
+ #
111
+ # Move the string to the <tt>n</tt>th column. Relative indentation is preserved.
112
+ # Column indices begin at 0, so the result is that the leftmost character of
113
+ # the string has +n+ spaces before it.
114
+ #
115
+ # Examples:
116
+ # "xyz".tabto(0) # -> "xyz"
117
+ # "xyz".tabto(1) # -> " xyz"
118
+ # "xyz".tabto(2) # -> " xyz"
119
+ # " xyz".tabto(1) # -> " xyz"
120
+ #
121
+ # str = <<EOF
122
+ # Hello, my name
123
+ # is Gerald.
124
+ # EOF
125
+ # str.tabto(5) == <<EOF # -> true
126
+ # Hello, my name
127
+ # is Gerald.
128
+ # EOF
129
+ #
130
+ def tabto(n)
131
+ n = n.to_int
132
+ n = 0 if n < 0
133
+ find = " " * leftmost_indent()
134
+ replace = " " * (n)
135
+ gsub(/^#{find}/, replace)
136
+ end
137
+ end
138
+ end
139
+
140
+
141
+ ExtensionsProject.implement(String, :taballto) do
142
+ class String
143
+ #
144
+ # Tabs all lines in the string to column +n+. That is, relative indentation
145
+ # is _not_ preserved.
146
+ #
147
+ def taballto(n)
148
+ n = n.to_int
149
+ n = 0 if n < 0
150
+ gsub(/^[ \t]*/, " "*n)
151
+ end
152
+ end
153
+ end
154
+
155
+
156
+ ExtensionsProject.implement(String, :trim) do
157
+ class String
158
+ #
159
+ # Trims a string:
160
+ # - removes one initial blank line
161
+ # - removes trailing spaces on each line
162
+ # - if +margin+ is given, removes initial spaces up to and including
163
+ # the margin on each line, plus one space
164
+ #
165
+ # This is designed specifically for working with inline documents.
166
+ # Here-documents are great, except they tend to go against the indentation
167
+ # of your code. This method allows a convenient way of using %{}-style
168
+ # documents. For instance:
169
+ #
170
+ # USAGE = %{
171
+ # | usage: prog [-o dir] -h file...
172
+ # | where
173
+ # | -o dir outputs to DIR
174
+ # | -h prints this message
175
+ # }.trim("|")
176
+ #
177
+ # # USAGE == "usage: prog [-o dir] -h file...\n where"...
178
+ # # (note single space to right of margin is deleted)
179
+ #
180
+ # Note carefully that if no margin string is given, then there is no
181
+ # clipping at the beginning of each line and your string will remain
182
+ # indented. You can use <tt>tabto(0)</tt> to align it with the left of
183
+ # screen (while preserving relative indentation).
184
+ #
185
+ # USAGE = %{
186
+ # usage: prog [-o dir] -h file...
187
+ # where
188
+ # -o dir outputs to DIR
189
+ # -h prints this message
190
+ # }.trim.tabto(0)
191
+ #
192
+ # # USAGE == (same as last example)
193
+ #
194
+ def trim(margin=nil)
195
+ s = self.dup
196
+ # Remove initial blank line.
197
+ s.sub!(/\A[ \t]*\n/, "")
198
+ # Get rid of the margin, if it's specified.
199
+ unless margin.nil?
200
+ margin_re = Regexp.escape(margin || "")
201
+ margin_re = /^[ \t]*#{margin_re} ?/
202
+ s.gsub!(margin_re, "")
203
+ end
204
+ # Remove trailing whitespace on each line
205
+ s.gsub!(/[ \t]+$/, "")
206
+ s
207
+ end
208
+ end
209
+ end
210
+
211
+
212
+ ExtensionsProject.implement(String, :starts_with?) do
213
+ class String
214
+ #
215
+ # Returns true iff this string starts with +str+.
216
+ # "Hello, world".starts_with?("He") # -> true
217
+ # "Hello, world".starts_with?("Green") # -> false
218
+ #
219
+ def starts_with?(str)
220
+ str = str.to_str
221
+ head = self[0, str.length]
222
+ head == str
223
+ end
224
+ end
225
+ end
226
+
227
+
228
+ ExtensionsProject.implement(String, :ends_with?) do
229
+ class String
230
+ #
231
+ # Returns true iff this string ends with +str+.
232
+ # "Hello, world".ends_with?(", world") # -> true
233
+ # "Hello, world".ends_with?("Green") # -> false
234
+ #
235
+ def ends_with?(str)
236
+ str = str.to_str
237
+ tail = self[-str.length, str.length]
238
+ tail == str
239
+ end
240
+ end
241
+ end
242
+
243
+
244
+ ExtensionsProject.implement(String, :line) do
245
+ class String
246
+ #
247
+ # Returns a line or lines from the string. +args+ can be a single integer,
248
+ # two integers or a range, as per <tt>Array#slice</tt>. The return value is
249
+ # a single String (a single line), an array of Strings (multiple lines) or
250
+ # +nil+ (out of bounds). Note that lines themselves do not contain a
251
+ # trailing newline character; that is metadata. Indexes out of bounds are
252
+ # ignored.
253
+ #
254
+ # data = " one \n two \n three \n four \n five \n"
255
+ # data.line(1) # -> " two "
256
+ # data.line(0,1) # -> [" one "]
257
+ # data.line(3..9) # -> [" four ", " five "]
258
+ # data.line(9) # -> nil
259
+ #
260
+ def line(*args)
261
+ self.split(/\n/).slice(*args)
262
+ rescue TypeError
263
+ raise TypeError,
264
+ "String#line(*args): args must be one Integer, two Integers or a Range"
265
+ rescue ArgumentError
266
+ raise ArgumentError,
267
+ "String#line(*args): args must be one Integer, two Integers or a Range"
268
+ end
269
+ end
270
+ end
271
+
272
+
273
+ ExtensionsProject.implement(String, :cmp) do
274
+ class String
275
+ #
276
+ # Compare this string to +other+, returning the first index at which they
277
+ # differ, or +nil+ if they are equal.
278
+ #
279
+ # "practise".cmp("practice") # -> 6
280
+ # "noun".cmp("nouns") # -> 5 (and vice versa)
281
+ # "fly".cmp("fly") # -> nil
282
+ #
283
+ def cmp(other)
284
+ other = other.to_str
285
+ if self == other
286
+ return nil
287
+ else
288
+ n = [self.size, other.size].min
289
+ (0..n).each do |i|
290
+ return i unless self[i] == other[i]
291
+ end
292
+ end
293
+ end
294
+ end
295
+ end
296
+
297
+
298
+ ExtensionsProject.implement(String, :join) do
299
+ class String
300
+ #
301
+ # Join all the lines of the string together, and compress spaces. The resulting string
302
+ # will have no surrounding whitespace.
303
+ #
304
+ # text = %{
305
+ # Once upon a time,
306
+ # Little Red Riding Hood ...
307
+ #
308
+ # }
309
+ #
310
+ # text.join # -> "Once upon a time, Little Red Riding Hood ..."
311
+ #
312
+ def join
313
+ gsub(/([ \t]*\n[ \t]*)+/, ' ').strip
314
+ end
315
+ end
316
+ end
@@ -0,0 +1,28 @@
1
+ #!/usr/local/bin/ruby -w
2
+ #
3
+ # == extensions/symbol.rb
4
+ #
5
+ # Adds methods to the builtin Symbol class.
6
+ #
7
+
8
+ require "extensions/_base"
9
+
10
+
11
+ #
12
+ # * Symbol#to_proc
13
+ #
14
+ ExtensionsProject.implement(Symbol, :to_proc) do
15
+ class Symbol
16
+ #
17
+ # Allows a Symbol to be implicitly converted to a Proc.
18
+ #
19
+ # This allows such conveniences as:
20
+ # %{john terry fiona}.map(&:capitalize) # -> %{John Terry Fiona}
21
+ # sum = numbers.inject(&:+)
22
+ #
23
+ def to_proc
24
+ proc { |obj, *args| obj.send(self, *args) }
25
+ end
26
+ end
27
+ end
28
+
metadata CHANGED
@@ -1,10 +1,10 @@
1
1
  --- !ruby/object:Gem::Specification
2
- rubygems_version: 0.8.3
2
+ rubygems_version: 0.8.4
3
3
  specification_version: 1
4
4
  name: og
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.7.0
7
- date: 2004-12-27
6
+ version: 0.8.0
7
+ date: 2005-01-12
8
8
  summary: Og (ObjectGraph)
9
9
  require_paths:
10
10
  - lib
@@ -34,6 +34,7 @@ files:
34
34
  - Rakefile
35
35
  - ChangeLog.1
36
36
  - ChangeLog
37
+ - examples/og/mysql_to_psql.rb
37
38
  - examples/og/run.rb
38
39
  - examples/og/mock_example.rb
39
40
  - examples/og/README
@@ -46,13 +47,15 @@ files:
46
47
  - lib/glue/number.rb
47
48
  - lib/glue/time.rb
48
49
  - lib/glue/property.rb
49
- - lib/glue/property.rb.old
50
50
  - lib/glue/macro.rb
51
51
  - lib/glue/cache.rb
52
52
  - lib/glue/string.rb
53
53
  - lib/glue/array.rb
54
+ - lib/glue/validation.rb
55
+ - lib/glue/attribute.rb
54
56
  - lib/og/backends
55
57
  - lib/og/version.rb
58
+ - lib/og/enchant.rb
56
59
  - lib/og/connection.rb
57
60
  - lib/og/mock.rb
58
61
  - lib/og/meta.rb
@@ -62,6 +65,23 @@ files:
62
65
  - lib/og.rb
63
66
  - test/tc_og.rb
64
67
  - test/og/tc_lifecycle.rb
68
+ - vendor/extensions/enumerable.rb
69
+ - vendor/extensions/all.rb
70
+ - vendor/extensions/hash.rb
71
+ - vendor/extensions/continuation.rb
72
+ - vendor/extensions/module.rb
73
+ - vendor/extensions/binding.rb
74
+ - vendor/extensions/ostruct.rb
75
+ - vendor/extensions/kernel.rb
76
+ - vendor/extensions/class.rb
77
+ - vendor/extensions/numeric.rb
78
+ - vendor/extensions/_base.rb
79
+ - vendor/extensions/io.rb
80
+ - vendor/extensions/string.rb
81
+ - vendor/extensions/object.rb
82
+ - vendor/extensions/array.rb
83
+ - vendor/extensions/symbol.rb
84
+ - vendor/extensions/_template.rb
65
85
  test_files: []
66
86
  rdoc_options:
67
87
  - "--main"
@@ -1,307 +0,0 @@
1
- # code:
2
- # * George Moschovitis <gm@navel.gr>
3
- # design:
4
- # * Anastastios Koutoumanos <ak@navel.gr>
5
- # * Elias Karakoulakis <ekarak@ktismata.com>
6
- #
7
- # (c) 2004 Navel, all rights reserved.
8
- # $Id: property.rb 185 2004-12-10 13:29:09Z gmosx $
9
-
10
- require "glue/array"
11
- require "glue/hash"
12
-
13
- module G
14
-
15
- # = Property
16
- #
17
- # Ruby attributes are typeless and generally this is good. Some times
18
- # we need extra metadata though, for example in relational mapping,
19
- # or web form population.
20
- #
21
- # Only Fixnums, Strings, Floats, Times, Booleans are converted.
22
- #
23
- # The default = methods do not force the types. A special
24
- # __force_set method should be used instead.
25
- #
26
- #--
27
- # TODO:
28
- # Inject only the really needd methods into Module.
29
- # Perhaps a sync is needed in evals (!!!!)
30
- #++
31
- #
32
- class Property
33
- # the symbol of the property
34
- attr_accessor :symbol
35
- # the string representation of the symbol
36
- attr_accessor :name
37
- # the class of the property
38
- attr_accessor :klass
39
- # additional metadata (like sql declaratio, sql index, etc)
40
- attr_accessor :meta
41
-
42
- def initialize(symbol, klass, meta = {})
43
- @symbol, @klass = symbol, klass
44
- @meta = meta
45
- @name = @symbol.to_s()
46
- end
47
-
48
- def ==(other)
49
- return @symbol == other.symbol
50
- end
51
-
52
- def to_s
53
- return name
54
- end
55
- end
56
-
57
- end # module
58
-
59
- class Module
60
-
61
- # Define a property (== typed attribute)
62
- # This works like Ruby's standard attr method, ie creates
63
- # only one property.
64
- #
65
- # Use the prop_reader, prop_writer, prop_accessor methods
66
- # for multiple properties.
67
- #
68
- # Examples:
69
- # prop String, :name, :sql => "char(32), :sql_index => "name(32)"
70
- # --> creates only writer.
71
- # prop Fixnum, :oid, writer = true, :sql => "integer PRIMARY KEY"
72
- # --> creates reader and writer.
73
- #
74
- def prop(*params)
75
- meta = {}
76
- klass = Object
77
-
78
- for param in params
79
- if param.is_a?(Class)
80
- klass = param
81
- elsif param.is_a?(Symbol)
82
- symbol = param
83
- elsif param.is_a?(TrueClass) or param.is_a?(TrueClass)
84
- writer = param
85
- elsif param.is_a?(Hash)
86
- # the meta hash.
87
- meta = param
88
- else
89
- raise "Error when defining property!"
90
- end
91
- end
92
-
93
- unless self.methods.include?(:__props)
94
- eval %{
95
- # Properties
96
- # An array is used to enforce order.
97
- def __props
98
- @__props
99
- end
100
-
101
- def __props=(props)
102
- @__props = props
103
- end
104
-
105
- def __meta
106
- @__meta
107
- end
108
-
109
- def __meta=(meta)
110
- @__meta = meta
111
- end
112
- }
113
- end
114
-
115
- @__props = G::SafeArray.new() unless @__props
116
-
117
- property = G::Property.new(symbol, klass, meta)
118
-
119
- reader = meta[:reader] || true
120
- writer = writer || meta[:writer] || false
121
-
122
- __add_prop(property, reader, writer)
123
- end
124
-
125
- # Helper method. Accepts a collection of symbols and generates
126
- # properties. Only generates reader.
127
- #
128
- # Example:
129
- # prop_reader String, :name, :title, :body, :sql => "char(32)"
130
- #
131
- def prop_reader(*params)
132
- meta = {}
133
- klass = Object
134
- symbols = []
135
-
136
- for param in params
137
- if param.is_a?(Class)
138
- klass = param
139
- elsif param.is_a?(Symbol)
140
- symbols << param
141
- elsif param.is_a?(Hash)
142
- # the meta hash.
143
- meta = param
144
- else
145
- raise "Error when defining property!"
146
- end
147
- end
148
-
149
- meta[:reader] = true
150
- meta[:writer] = false
151
-
152
- for symbol in symbols
153
- prop(klass, symbol, meta)
154
- end
155
- end
156
-
157
- # Helper method. Accepts a collection of symbols and generates
158
- # properties. Only generates writer.
159
- #
160
- # Example:
161
- # prop_writer String, :name, :title, :body, :sql => "char(32)"
162
- #
163
- def prop_writer(*params)
164
- meta = {}
165
- klass = Object
166
- symbols = []
167
-
168
- for param in params
169
- if param.is_a?(Class)
170
- klass = param
171
- elsif param.is_a?(Symbol)
172
- symbols << param
173
- elsif param.is_a?(Hash)
174
- # the meta hash.
175
- meta = param
176
- else
177
- raise "Error when defining property!"
178
- end
179
- end
180
-
181
- meta[:reader] = false
182
- meta[:writer] = true
183
-
184
- for symbol in symbols
185
- prop(klass, symbol, meta)
186
- end
187
- end
188
-
189
- # Helper method. Accepts a collection of symbols and generates
190
- # properties. Generates reader and writer.
191
- #
192
- # Example:
193
- # prop_accessor String, :name, :title, :body, :sql => "char(32)"
194
- #
195
- def prop_accessor(*params)
196
- meta = {}
197
- klass = Object
198
- symbols = []
199
-
200
- for param in params
201
- if param.is_a?(Class)
202
- klass = param
203
- elsif param.is_a?(Symbol)
204
- symbols << param
205
- elsif param.is_a?(Hash)
206
- # the meta hash.
207
- meta = param
208
- else
209
- raise "Error when defining property!"
210
- end
211
- end
212
-
213
- meta[:reader] = true
214
- meta[:writer] = true
215
-
216
- for symbol in symbols
217
- prop(klass, symbol, meta)
218
- end
219
- end
220
-
221
- # Add the property
222
- #
223
- def __add_prop(prop, reader = true, writer = true)
224
- if idx = @__props.index(prop)
225
- # override in case of duplicates. Keep the order of the props.
226
- @__props[idx] = prop
227
- else
228
- @__props << prop
229
- end
230
-
231
- # Precompile the property read/write methods
232
-
233
- s, klass = prop.symbol, prop.klass
234
-
235
- if reader
236
- module_eval %{
237
- def #{s}
238
- return @#{s}
239
- end
240
- }
241
- end
242
-
243
- # gmosx: __force_xxx reuses xxx= to allow for easier
244
- # overrides.
245
- if writer
246
- module_eval %{
247
- def #{s}=(val)
248
- @#{s} = val
249
- end
250
-
251
- def __force_#{s}(val)
252
- self.#{s}=(} + case klass.name
253
- when Fixnum.name
254
- "val.to_i()"
255
- when String.name
256
- "val.to_s()"
257
- when Float.name
258
- "val.to_f()"
259
- when Time.name
260
- "Time.parse(val.to_s())"
261
- when TrueClass.name, FalseClass.name
262
- "val.to_i() > 0"
263
- else
264
- "val"
265
- end + %{)
266
- end
267
- }
268
- end
269
- end
270
-
271
- # Attach metadata
272
- #
273
- def meta(key, val)
274
- @__meta = G::SafeHash.new unless @__meta
275
-
276
- @__meta[key] = [] unless @__meta[key]
277
-
278
- # guard against duplicates, no need to keep order.
279
- @__meta[key].delete_if { |v| val == v }
280
- @__meta[key] << val
281
- end
282
-
283
- # This method is typically called before including other
284
- # modules to preserve properties order.
285
- #
286
- def inherit_meta(mod = superclass)
287
- # concat props.
288
- if mod.__props
289
- @__props = G::SafeArray.new unless @__props
290
-
291
- mod.__props.each { |p|
292
- __add_prop(p)
293
- }
294
- end
295
-
296
- # concat metadata
297
- if mod.__meta
298
- mod.__meta.each { |k, val|
299
- val.each { |v|
300
- meta(k, v)
301
- } if val
302
- }
303
- end
304
- end
305
-
306
- end
307
-