og 0.8.0 → 0.9.3

Sign up to get free protection for your applications and to get access to all the features.
data/README.og CHANGED
@@ -1,4 +1,4 @@
1
- = Og 0.8.0
1
+ = Og 0.9.0
2
2
 
3
3
  Nitro integrates the Og (ObjectGraph) object-relational mapping
4
4
  library. Og provides transparent serialization of object graphs to a RDBMS
@@ -41,40 +41,44 @@ The library provides the following features:
41
41
  + Hierarchical structures (preorder traversal, materialized paths)
42
42
  + Works safely as part of distributed application.
43
43
  + Automatic Validation/Constraints.
44
- + Simple implementation < 2k lines of code.
44
+ + Simple and clean implementation.
45
45
 
46
46
  == Download
47
47
 
48
48
  The latest version of Og can be found at
49
49
 
50
- * http://www.navel.gr/og
50
+ * http://www.rubyforge.com/projects/nitro
51
51
 
52
- Documentation for Og can be found at
53
-
54
- * http://www.navel.gr/nitro/og
52
+ Documentation for Og can be found in the distribution.
55
53
 
56
54
 
57
55
  == Requirements
58
56
 
59
57
  Og requires the following applications or libraries:
60
58
 
61
- * Ruby 1.8.1 and greater (http://www.ruby-lang.org)
62
- Version 1.8.2.preview2 is recomended
59
+ * Ruby 1.8.1 and greater
60
+ http://www.ruby-lang.org
61
+ Version 1.8.2 is recomended.
63
62
 
64
- * Ruby-psql (http://www.postgresql.jp/interfaces/ruby/archive/ruby-postgres-0.7.1.tar.gz)
63
+ * Ruby-psql
64
+ http://www.postgresql.jp/interfaces/ruby/archive/ruby-postgres-0.7.1.tar.gz
65
65
  Ruby interface to the PostgreSQL RDBMS.
66
66
 
67
- * Ruby-mysql (http://tmtm.org/ja/ruby/mysql/README_en.html)
67
+ * Ruby-mysql
68
+ http://tmtm.org/ja/ruby/mysql/README_en.html
68
69
  Ruby interface to the MySQL RDBMS.
69
70
 
70
- * PostgreSQL (http://www.postgres.org)
71
+ * PostgreSQL
72
+ http://www.postgres.org
71
73
  Used for the Database Backend.
72
74
 
73
- * MySQL (http://www.mysql.org)
75
+ * MySQL
76
+ http://www.mysql.org
74
77
  Used for the Database Backend.
75
78
 
76
79
  Please install the required applications and libraries before continuing
77
- with the installation of Og.
80
+ with the installation of Og. Only install the libraries needed for
81
+ the backend you plan to use.
78
82
 
79
83
 
80
84
  == Instalation
@@ -82,11 +86,11 @@ with the installation of Og.
82
86
  Og is distributed as a RubyGem. First of all make sure you have
83
87
  installed RubyGems on your system. Then run the following command:
84
88
 
85
- gem install og-rml
89
+ gem install og
86
90
 
87
91
  Then try to run the examples/og Example application.
88
92
 
89
- A tar.gz distribution is also available on http://www.navel.gr/og
93
+ A tar.gz distribution is also available on http://www.rubyforge.com/projects/nitro.
90
94
 
91
95
 
92
96
  == Support
@@ -98,7 +102,7 @@ mailto:gm@navel.gr.
98
102
 
99
103
  == Licence
100
104
 
101
- Copyright (c) 2004 Navel Ltd (http://www.navel.gr)
105
+ Copyright (c) 2004-2005 Navel Ltd (http://www.navel.gr)
102
106
 
103
107
  Og (http://www.navel.gr/og) is copyrighted free software
104
108
  created and maintained by George Moschovitis (mailto:gm@navel.gr)
@@ -1,3 +1,21 @@
1
+ == Version 0.9.3 was released on 01/02/2005.
2
+
3
+ A maintenance release.
4
+
5
+ Most notable additions:
6
+
7
+ * Og metalanguage relations insert metadata into
8
+ the target class, useful for advanced scaffolders.
9
+
10
+ * Og refer_to meta-language command.
11
+
12
+ * Correct handling of booleans.
13
+
14
+ * Auto-include metalanguage on prop.
15
+
16
+ * Many bug fixes.
17
+
18
+
1
19
  == Version 0.8 was released on 12/01/2005.
2
20
 
3
21
  A snapshot of the latest code. Cool new features,
data/Rakefile CHANGED
@@ -1,8 +1,6 @@
1
- # code:
2
1
  # * George Moschovitis <gm@navel.gr>
3
- #
4
- # (c) 2004 Navel, all rights reserved.
5
- # $Id: connection.rb 71 2004-10-18 10:50:22Z gmosx $
2
+ # (c) 2004-2005 Navel, all rights reserved.
3
+ # $Id$
6
4
 
7
5
  require "rake"
8
6
  require "rake/rdoctask"
@@ -52,7 +50,7 @@ if 'nitro' == project
52
50
  #
53
51
  require "lib/nitro/version"
54
52
 
55
- PKG_VERSION = $srv_version
53
+ PKG_VERSION = Nitro::Version
56
54
  PKG_FILES = FileList[
57
55
  "[A-Z]*", "{bin,benchmark,etc,ext,examples,doc,lib,test,vendor}/**/*"
58
56
  # "examples/*.rb"
@@ -87,7 +85,7 @@ else
87
85
  #
88
86
  require "lib/og/version"
89
87
 
90
- PKG_VERSION = $og_version
88
+ PKG_VERSION = Og::Version
91
89
  PKG_FILES = FileList[
92
90
  "README.og", "RELEASES.og", "LICENSE", "AUTHORS", "Rakefile", "ChangeLog*",
93
91
  "examples/og/*", "lib/glue.rb", "lib/glue/**/*", "lib/og/**/*", "lib/og.rb",
@@ -114,7 +112,7 @@ else
114
112
  s.author = "George Moschovitis"
115
113
  s.email = "gm@navel.gr"
116
114
  s.homepage = "http://www.navel.gr/og"
117
- s.rubyforge_project = "og-rml"
115
+ s.rubyforge_project = "nitro"
118
116
  end
119
117
 
120
118
  end
@@ -6,7 +6,7 @@
6
6
  # * George Moschovitis <gm@navel.gr>
7
7
  #
8
8
  # (c) 2004 Navel, all rights reserved.
9
- # $Id: run.rb 198 2004-12-22 11:26:59Z gmosx $
9
+ # $Id: run.rb 202 2005-01-17 10:44:13Z gmosx $
10
10
 
11
11
  $:.unshift File.join(File.dirname(__FILE__), '..', '..', 'lib')
12
12
 
@@ -273,7 +273,7 @@ puts '---'
273
273
 
274
274
  c2.articles.each { |a| puts a.title }
275
275
 
276
- article.del_category(c1)
276
+ article.delete_category(c1)
277
277
 
278
278
  puts '---'
279
279
 
@@ -1,12 +1,10 @@
1
- # = Glue
2
- #
3
1
  # General libraries used by various projects.
4
2
  #
5
- # code:
6
- # * George Moschovitis <gm@navel.gr>
7
- #
3
+ #--
4
+ # George Moschovitis <gm@navel.gr>
8
5
  # (c) 2004-2005 Navel, all rights reserved.
9
- # $Id: glue.rb 175 2004-11-26 16:11:27Z gmosx $
6
+ # $Id: glue.rb 215 2005-01-24 10:44:05Z gmosx $
7
+ #++
10
8
 
11
9
  require 'English'
12
10
  require 'pp'
@@ -14,10 +12,15 @@ require 'pp'
14
12
  require 'glue/property'
15
13
  require 'glue/attribute'
16
14
 
15
+ # The standard namespace module.
16
+
17
+ module N; end
18
+
17
19
  class NilClass
20
+
18
21
  # quite usefull for error tolerant apps.
19
22
  # a bit dangerous? Will have to rethink this.
20
- #
23
+
21
24
  def empty?
22
25
  return true
23
26
  end
@@ -27,6 +30,7 @@ class Class
27
30
  #--
28
31
  # gmosx: is this really needed?
29
32
  #++
33
+
30
34
  def to_i
31
35
  return self.hash
32
36
  end
@@ -34,7 +38,7 @@ end
34
38
 
35
39
  module Kernel
36
40
 
37
- # pretty prints an exception/error object
41
+ # Pretty prints an exception/error object
38
42
  # usefull for helpfull debug messages
39
43
  #
40
44
  # Input:
@@ -42,7 +46,7 @@ module Kernel
42
46
  #
43
47
  # Output:
44
48
  # the pretty printed string
45
- #
49
+
46
50
  def pp_exception(ex)
47
51
  return %{#{ex.message}\n\tBACKTRACE:\n\t#{ex.backtrace.join("\n\t")}\n\tLOGGED FROM:\n\t#{caller[0]}}
48
52
  end
@@ -2,7 +2,7 @@
2
2
  # * George Moschovitis <gm@navel.gr>
3
3
  #
4
4
  # (c) 2002-2003 Navel, all rights reserved.
5
- # $Id: array.rb 165 2004-11-18 12:04:04Z gmosx $
5
+ # $Id: array.rb 202 2005-01-17 10:44:13Z gmosx $
6
6
 
7
7
  require "sync"
8
8
 
@@ -3,7 +3,7 @@
3
3
  # * Anastasios Koutoumanos <ak@navel.gr>
4
4
  #
5
5
  # (c) 2004 Navel, all rights reserved.
6
- # $Id: cache.rb 167 2004-11-23 14:03:10Z gmosx $
6
+ # $Id: cache.rb 202 2005-01-17 10:44:13Z gmosx $
7
7
 
8
8
  module N;
9
9
 
@@ -0,0 +1,12 @@
1
+ # * George Moschovitis <gm@navel.gr>
2
+ # (c) 2004-2005 Navel, all rights reserved.
3
+ # $Id$
4
+
5
+ require 'ostruct'
6
+
7
+ # A flexible Object.
8
+ # Temporarily implemented as a simple OpenStruct.
9
+
10
+ class Flexob < OpenStruct
11
+
12
+ end
@@ -2,7 +2,7 @@
2
2
  # * George Moschovitis <gm@navel.gr>
3
3
  #
4
4
  # (c) 2004 Navel, all rights reserved.
5
- # $Id: hash.rb 167 2004-11-23 14:03:10Z gmosx $
5
+ # $Id: hash.rb 202 2005-01-17 10:44:13Z gmosx $
6
6
 
7
7
  require "sync"
8
8
 
@@ -44,13 +44,13 @@ module Inflector
44
44
  end
45
45
 
46
46
  # Convert a class to a name.
47
- #
47
+
48
48
  def name(klass)
49
49
  Inflector.underscore(Inflector.demodulize(klass.to_s))
50
50
  end
51
51
 
52
52
  # Convert a class to a name in plural
53
- #
53
+
54
54
  def plural_name(klass)
55
55
  Inflector.pluralize(Inflector.underscore(Inflector.demodulize(klass.to_s)))
56
56
  end
@@ -1,16 +1,12 @@
1
- # code:
2
1
  # * George Moschovitis <gm@navel.gr>
3
- #
4
- # (c) 2004 Navel, all rights reserved.
5
- # $Id: logger.rb 161 2004-11-18 10:51:51Z gmosx $
2
+ # (c) 2004-2005 Navel, all rights reserved.
3
+ # $Id: logger.rb 248 2005-01-31 13:38:34Z gmosx $
6
4
 
7
5
  require 'logger'
8
6
 
9
- # = Logger
10
- #
11
7
  # A simple wrapper arround the Ruby logger. Mainly for
12
8
  # compatibility purposes.
13
- #
9
+
14
10
  class Logger
15
11
  alias_method :devel, :debug
16
12
  alias_method :fine, :debug
@@ -42,7 +38,7 @@ class Logger
42
38
  #
43
39
  # This code comes straight from the dev-utils Gem.
44
40
  # Author: Gavin Sinclair <gsinclair@soyabean.com.au>
45
- #
41
+
46
42
  def trace(expr, style=:p)
47
43
  unless expr.respond_to? :to_str
48
44
  warn "trace: Can't evaluate the given value: #{caller.first}"
@@ -0,0 +1,14 @@
1
+ # * George Moschovitis <gm@navel.gr>
2
+ # (c) 2004-2005 Navel, all rights reserved.
3
+ # $Id$
4
+
5
+ # Executes a Ruby block without warnings.
6
+
7
+ def silence_warnings
8
+ old_verbose, $VERBOSE = $VERBOSE, nil
9
+ begin
10
+ yield
11
+ ensure
12
+ $VERBOSE = old_verbose
13
+ end
14
+ end
@@ -2,7 +2,7 @@
2
2
  # * George Moschovitis <gm@navel.gr>
3
3
  #
4
4
  # (c) 2004 Navel, all rights reserved.
5
- # $Id: number.rb 167 2004-11-23 14:03:10Z gmosx $
5
+ # $Id: number.rb 202 2005-01-17 10:44:13Z gmosx $
6
6
 
7
7
  module N;
8
8
 
@@ -0,0 +1,26 @@
1
+ # $Id$
2
+
3
+ class Object #:nodoc:
4
+ def remove_subclasses_of(superclass)
5
+ subclasses_of(superclass).each { |subclass| Object.send(:remove_const, subclass) rescue nil }
6
+ end
7
+
8
+ def subclasses_of(superclass)
9
+ subclasses = []
10
+ ObjectSpace.each_object(Class) do |k|
11
+ next if !k.ancestors.include?(superclass) || superclass == k || k.to_s.include?("::") || subclasses.include?(k.to_s)
12
+ subclasses << k.to_s
13
+ end
14
+ subclasses
15
+ end
16
+ end
17
+
18
+ class Class #:nodoc:
19
+ def remove_subclasses
20
+ Object.remove_subclasses_of(self)
21
+ end
22
+
23
+ def subclasses
24
+ Object.subclasses_of(self)
25
+ end
26
+ end
@@ -2,7 +2,7 @@
2
2
  # * George Moschovitis <gm@navel.gr>
3
3
  #
4
4
  # (c) 2004 Navel, all rights reserved.
5
- # $Id: pool.rb 167 2004-11-23 14:03:10Z gmosx $
5
+ # $Id: pool.rb 202 2005-01-17 10:44:13Z gmosx $
6
6
 
7
7
  require "thread"
8
8
  require "monitor"
@@ -1,21 +1,19 @@
1
- # code:
2
1
  # * George Moschovitis <gm@navel.gr>
3
- #
4
- # (c) 2004 Navel, all rights reserved.
5
- # $Id: property.rb 200 2004-12-27 11:24:41Z gmosx $
2
+ # * Michael Neumann <mneumann@ntecs.de>
3
+ # (c) 2004-2005 Navel, all rights reserved.
4
+ # $Id: property.rb 248 2005-01-31 13:38:34Z gmosx $
6
5
 
7
6
  require 'glue/array'
8
7
  require 'glue/hash'
9
8
 
10
9
  module N
11
10
 
12
- # = Property
13
- #
14
- # Ruby attributes are typeless and generally this is good. Some times
15
- # we need extra metadata though, for example in relational mapping,
16
- # or web form population.
11
+ # Ruby attributes are typeless and generally this is good.
12
+ # Some times we need extra metadata though, for example in
13
+ # relational mapping, or web form population.
17
14
  #
18
- # Only Fixnums, Strings, Floats, Times, Booleans are converted.
15
+ # Only Fixnums, Strings, Floats, Times, Booleans are
16
+ # converted.
19
17
  #
20
18
  # The default = methods do not force the types. A special
21
19
  # __force_set method should be used instead.
@@ -24,14 +22,23 @@ module N
24
22
  # TODO:
25
23
  # Perhaps a sync is needed in evals (!!!!)
26
24
  #++
25
+
27
26
  class Property
27
+
28
28
  # the symbol of the property
29
+
29
30
  attr_accessor :symbol
31
+
30
32
  # the string representation of the symbol
33
+
31
34
  attr_accessor :name
35
+
32
36
  # the class of the property
37
+
33
38
  attr_accessor :klass
39
+
34
40
  # additional metadata (like sql declaration, sql index, etc)
41
+
35
42
  attr_accessor :meta
36
43
 
37
44
  def initialize(symbol, klass, meta = {})
@@ -53,7 +60,7 @@ end
53
60
  # = PropertyUtils
54
61
  #
55
62
  # A collection of Property related utility methods.
56
- #
63
+
57
64
  module PropertyUtils
58
65
 
59
66
  # Add accessors to the properties to the given target
@@ -65,6 +72,7 @@ module PropertyUtils
65
72
  #--
66
73
  # gmosx: Perhaps we 'll optimize this in the future.
67
74
  #++
75
+
68
76
  def self.enchant(target, force = false)
69
77
  unless target.singleton_methods.include?('__props')
70
78
  target.module_eval <<-"end_eval", __FILE__, __LINE__
@@ -91,7 +99,7 @@ module PropertyUtils
91
99
  end
92
100
 
93
101
  # Copy properties from src (Module or Class) to dest.
94
- #
102
+
95
103
  def self.copy_props(src, dest)
96
104
  src.__props.each do |p|
97
105
  add_prop(dest, p)
@@ -105,7 +113,7 @@ module PropertyUtils
105
113
  end
106
114
 
107
115
  # Add the property to the target (Class or Module)
108
- #
116
+
109
117
  def self.add_prop(target, prop)
110
118
  if idx = target.__props.index(prop)
111
119
  # override in case of duplicates. Keep the order of the props.
@@ -128,6 +136,7 @@ module PropertyUtils
128
136
 
129
137
  # gmosx: __force_xxx reuses xxx= to allow for easier
130
138
  # overrides.
139
+
131
140
  if prop.meta[:writer]
132
141
  target.module_eval %{
133
142
  #{prop_setter(prop)}
@@ -154,7 +163,7 @@ module PropertyUtils
154
163
 
155
164
  # Generates the property setter code. Can be overriden
156
165
  # to support extra functionality (example: markup)
157
- #
166
+
158
167
  def self.prop_setter(prop)
159
168
  s = prop.symbol
160
169
  %{
@@ -165,11 +174,53 @@ module PropertyUtils
165
174
  end
166
175
 
167
176
  # Get the property metadata for the given symbol.
168
- #
177
+
169
178
  def self.get_prop(klass, sym)
170
179
  return klass.__props.find { |p| p.symbol == sym }
171
180
  end
172
181
 
182
+ # Include meta-language mixins
183
+
184
+ def self.include_meta_mixins(target)
185
+ target.module_eval %{ include N::Validation } if defined?(N::Validation)
186
+ # gmosx: TODO, make Og::MetaLanguage equivalent to Validation.
187
+ target.module_eval %{ extend Og::MetaLanguage } if defined?(Og::MetaLanguage)
188
+ end
189
+
190
+ # Resolves the parameters passed to the propxxx macros
191
+ # to generate the meta, klass and symbols variables. This
192
+ # way the common functionality is factored out.
193
+ #
194
+ # [+params+]
195
+ # The params to resolve.
196
+ # [+one_symbol+]
197
+ # If true, only resolves one symbol (used in prop).
198
+
199
+ def self.resolve_prop_params(*params)
200
+ meta = {}
201
+ klass = Object
202
+ symbols = []
203
+
204
+ for param in params.flatten
205
+ if param.is_a?(Class)
206
+ klass = param
207
+ elsif param.is_a?(Symbol)
208
+ symbols << param
209
+ elsif param.is_a?(TrueClass) or param.is_a?(TrueClass)
210
+ writer = param
211
+ elsif param.is_a?(Hash)
212
+ # the meta hash.
213
+ meta.update(param) { |k, a, b| [a,b].join(' ') }
214
+ else
215
+ raise 'Error when defining property!'
216
+ end
217
+ end
218
+
219
+ raise 'No symbols provided!' if symbols.empty?
220
+
221
+ return meta, klass, symbols
222
+ end
223
+
173
224
  end
174
225
 
175
226
  end # module
@@ -188,33 +239,19 @@ class Module
188
239
  # --> creates only writer.
189
240
  # prop Fixnum, :oid, writer = true, :sql => "integer PRIMARY KEY"
190
241
  # --> creates reader and writer.
191
- #
242
+
192
243
  def prop(*params)
193
-
194
- meta = {}
195
- klass = Object
196
-
197
- for param in params
198
- if param.is_a?(Class)
199
- klass = param
200
- elsif param.is_a?(Symbol)
201
- symbol = param
202
- elsif param.is_a?(TrueClass) or param.is_a?(TrueClass)
203
- writer = param
204
- elsif param.is_a?(Hash)
205
- # the meta hash.
206
- meta = param
207
- else
208
- raise "Error when defining property!"
209
- end
210
- end
244
+ meta, klass, symbols = N::PropertyUtils.resolve_prop_params(params)
245
+ symbol = symbols.first
211
246
 
247
+
212
248
  N::PropertyUtils.enchant(self)
213
249
 
214
250
  if self.is_a?(Class)
215
251
 
216
252
  # Add some extra code to append features to
217
253
  # subclasses.
254
+
218
255
  self.module_eval <<-"end_eval", __FILE__, __LINE__
219
256
 
220
257
  def self.inherited(sub)
@@ -231,17 +268,17 @@ class Module
231
268
 
232
269
  # Add some extra code for modules to append
233
270
  # their features to classes that include it.
271
+
234
272
  self.module_eval <<-"end_eval", __FILE__, __LINE__
235
273
 
236
274
  def self.append_features(base)
237
275
  N::PropertyUtils.enchant(base)
238
276
  N::PropertyUtils.copy_props(self, base)
277
+
239
278
  # gmosx: We have to define @@__props first to avoid reusing
240
279
  # the hash from the module. super must stay at the end.
241
-
242
- unless base.included_modules.include?(N::Validation)
243
- base.module_eval %{ include N::Validation }
244
- end if defined?(N::Validation)
280
+
281
+ N::PropertyUtils.include_meta_mixins(base)
245
282
 
246
283
  super
247
284
  end
@@ -265,7 +302,8 @@ class Module
265
302
  N::PropertyUtils.add_prop(self, property)
266
303
 
267
304
  # gmosx: should be placed AFTER enchant!
268
- module_eval %{ include N::Validation } if defined?(N::Validation)
305
+
306
+ N::PropertyUtils.include_meta_mixins(self)
269
307
  end
270
308
 
271
309
  # Helper method. Accepts a collection of symbols and generates
@@ -273,24 +311,9 @@ class Module
273
311
  #
274
312
  # Example:
275
313
  # prop_reader String, :name, :title, :body, :sql => "char(32)"
276
- #
314
+
277
315
  def prop_reader(*params)
278
- meta = {}
279
- klass = Object
280
- symbols = []
281
-
282
- for param in params
283
- if param.is_a?(Class)
284
- klass = param
285
- elsif param.is_a?(Symbol)
286
- symbols << param
287
- elsif param.is_a?(Hash)
288
- # the meta hash.
289
- meta = param
290
- else
291
- raise "Error when defining property!"
292
- end
293
- end
316
+ meta, klass, symbols = N::PropertyUtils.resolve_prop_params(params)
294
317
 
295
318
  meta[:reader] = true
296
319
  meta[:writer] = false
@@ -305,25 +328,10 @@ class Module
305
328
  #
306
329
  # Example:
307
330
  # prop_writer String, :name, :title, :body, :sql => "char(32)"
308
- #
331
+
309
332
  def prop_writer(*params)
310
- meta = {}
311
- klass = Object
312
- symbols = []
333
+ meta, klass, symbols = N::PropertyUtils.resolve_prop_params(params)
313
334
 
314
- for param in params
315
- if param.is_a?(Class)
316
- klass = param
317
- elsif param.is_a?(Symbol)
318
- symbols << param
319
- elsif param.is_a?(Hash)
320
- # the meta hash.
321
- meta = param
322
- else
323
- raise 'Error when defining property!'
324
- end
325
- end
326
-
327
335
  meta[:reader] = false
328
336
  meta[:writer] = true
329
337
 
@@ -337,25 +345,10 @@ class Module
337
345
  #
338
346
  # Example:
339
347
  # prop_accessor String, :name, :title, :body, :sql => "char(32)"
340
- #
348
+
341
349
  def prop_accessor(*params)
342
- meta = {}
343
- klass = Object
344
- symbols = []
350
+ meta, klass, symbols = N::PropertyUtils.resolve_prop_params(params)
345
351
 
346
- for param in params
347
- if param.is_a?(Class)
348
- klass = param
349
- elsif param.is_a?(Symbol)
350
- symbols << param
351
- elsif param.is_a?(Hash)
352
- # the meta hash.
353
- meta = param
354
- else
355
- raise "Error when defining property!"
356
- end
357
- end
358
-
359
352
  meta[:reader] = true
360
353
  meta[:writer] = true
361
354
 
@@ -371,6 +364,7 @@ class Module
371
364
  #--
372
365
  # gmosx: crappy implementation, recode.
373
366
  #++
367
+
374
368
  def meta(key, val)
375
369
  self.module_eval <<-"end_eval", __FILE__, __LINE__
376
370
  @@__meta[key] ||= []
@@ -380,4 +374,3 @@ class Module
380
374
  end
381
375
 
382
376
  end
383
-