og 0.6.0 → 0.7.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.
- data/ChangeLog +183 -0
- data/ChangeLog.1 +2344 -0
- data/README.og +4 -3
- data/RELEASES.og +15 -0
- data/Rakefile +135 -0
- data/examples/og/README +7 -0
- data/examples/og/mock_example.rb +58 -0
- data/examples/og/run.rb +9 -5
- data/lib/glue/property.rb +166 -107
- data/lib/glue/property.rb.old +307 -0
- data/lib/og.rb +17 -6
- data/lib/og/backend.rb +34 -4
- data/lib/og/backends/mysql.rb +3 -17
- data/lib/og/backends/psql.rb +5 -17
- data/lib/og/meta.rb +41 -26
- data/lib/og/mock.rb +223 -0
- data/lib/og/version.rb +2 -2
- data/test/og/tc_lifecycle.rb +107 -0
- data/test/tc_og.rb +31 -4
- metadata +22 -14
data/README.og
CHANGED
@@ -1,15 +1,16 @@
|
|
1
1
|
= Og 0.6.0
|
2
2
|
|
3
|
-
Og (ObjectGraph)
|
3
|
+
Nitro integrates the Og (ObjectGraph) object-relational mapping
|
4
4
|
library. Og provides transparent serialization of object graphs to a RDBMS
|
5
5
|
backend. Unlike other similar libraries Og maps standard Ruby
|
6
6
|
objects to SQL tables and not vice versa. Og provides a meta language
|
7
7
|
to describe the relations between objects, a flexible and intuitive api
|
8
8
|
for querieng the database, raw access to the SQL language if needed
|
9
9
|
(for example to fine tune the automatically generated SQL tables, or
|
10
|
-
for custom queries), suports deserialization to Ruby objects or tuples
|
10
|
+
for custom queries), suports deserialization to Ruby objects or tuples,
|
11
|
+
automatically generates join tables for many_to_many relations
|
11
12
|
and provides a collection of usefull Mixins to synthesize common
|
12
|
-
|
13
|
+
Entities.
|
13
14
|
|
14
15
|
Og is a combination of the best features of Active Record and the
|
15
16
|
former O-R mapping library included in Nitro (NDB). Adapters for
|
data/RELEASES.og
CHANGED
@@ -1,3 +1,18 @@
|
|
1
|
+
== Version 0.7 was released on 27/12/2004.
|
2
|
+
|
3
|
+
A snapshot of the latest code. Many fixes and new features result
|
4
|
+
in a more mature product. Many thanks to the ruby hackers that sent
|
5
|
+
suggestions and patches used in this release!
|
6
|
+
|
7
|
+
Most notable additions:
|
8
|
+
|
9
|
+
* Totaly recoded prop_accessor mechanism, avoids polution of the Module
|
10
|
+
class.
|
11
|
+
* prop_accessors for Modules, allows synthesizing of managed objects
|
12
|
+
from Mixins.
|
13
|
+
* new automatically generated methods in Og.
|
14
|
+
* MockDatabase leverages the FlexMock object for easier unit testing.
|
15
|
+
|
1
16
|
== Version 0.6 was released on 13/12/2004.
|
2
17
|
|
3
18
|
This is a preview release, the api for the new features is not
|
data/Rakefile
ADDED
@@ -0,0 +1,135 @@
|
|
1
|
+
# code:
|
2
|
+
# * 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 $
|
6
|
+
|
7
|
+
require "rake"
|
8
|
+
require "rake/rdoctask"
|
9
|
+
require "rake/gempackagetask"
|
10
|
+
require "rake/testtask"
|
11
|
+
require "rubygems"
|
12
|
+
|
13
|
+
#project = 'nitro'
|
14
|
+
project = 'og'
|
15
|
+
|
16
|
+
# ----------------------------------------------------------------------
|
17
|
+
|
18
|
+
desc "Default Task"
|
19
|
+
task :default => :package
|
20
|
+
|
21
|
+
# ----------------------------------------------------------------------
|
22
|
+
|
23
|
+
# Run the tests
|
24
|
+
|
25
|
+
Rake::TestTask.new do |t|
|
26
|
+
t.libs << "test"
|
27
|
+
t.test_files = FileList["test/**/tc*.rb"].exclude("**/tc*og*.rb")
|
28
|
+
t.verbose = true
|
29
|
+
end
|
30
|
+
|
31
|
+
# Run all tests
|
32
|
+
|
33
|
+
Rake::TestTask.new(:test_all) do |t|
|
34
|
+
t.libs << "test"
|
35
|
+
t.test_files = FileList["test/**/tc*.rb"]
|
36
|
+
t.verbose = true
|
37
|
+
end
|
38
|
+
|
39
|
+
# ----------------------------------------------------------------------
|
40
|
+
|
41
|
+
Rake::RDocTask.new do |rd|
|
42
|
+
rd.main = "README"
|
43
|
+
rd.rdoc_dir = "rdoc"
|
44
|
+
rd.rdoc_files.include("README", "lib/**/*.rb")
|
45
|
+
end
|
46
|
+
|
47
|
+
# ----------------------------------------------------------------------
|
48
|
+
|
49
|
+
if 'nitro' == project
|
50
|
+
|
51
|
+
# Nitro GemSpec
|
52
|
+
#
|
53
|
+
require "lib/nitro/version"
|
54
|
+
|
55
|
+
PKG_VERSION = $srv_version
|
56
|
+
PKG_FILES = FileList[
|
57
|
+
"[A-Z]*", "{bin,benchmark,etc,ext,examples,doc,lib,test,vendor}/**/*"
|
58
|
+
# "examples/*.rb"
|
59
|
+
].exclude(".svn/**/*").exclude("*.og").exclude("**/*.log")
|
60
|
+
|
61
|
+
spec = Gem::Specification.new do |s|
|
62
|
+
s.name = "nitro"
|
63
|
+
s.version = PKG_VERSION
|
64
|
+
s.summary = "Web Engine"
|
65
|
+
s.description = "An efficient, yet simple engine for Web Applications"
|
66
|
+
# s.add_dependency("postgres-pr", ">= 0.3.0")
|
67
|
+
# s.add_dependency("postgres", ">= 0.7.1")
|
68
|
+
# s.add_dependency("extensions", ">= 0.5")
|
69
|
+
s.required_ruby_version = ">= 1.8.1"
|
70
|
+
s.files = PKG_FILES.to_a
|
71
|
+
s.require_path = "lib"
|
72
|
+
s.autorequire = "nitro"
|
73
|
+
s.has_rdoc = true
|
74
|
+
s.extra_rdoc_files = FileList["[A-Z]*"].exclude("*.og").to_a
|
75
|
+
s.rdoc_options << "--main" << "README" << "--title" << "Nitro Documentation"
|
76
|
+
s.test_files = []
|
77
|
+
s.bindir = "bin"
|
78
|
+
s.author = "George Moschovitis"
|
79
|
+
s.email = "gm@navel.gr"
|
80
|
+
s.homepage = "http://www.navel.gr/nitro"
|
81
|
+
s.rubyforge_project = "nitro"
|
82
|
+
end
|
83
|
+
|
84
|
+
else
|
85
|
+
|
86
|
+
# Og stand-alone GemSpec
|
87
|
+
#
|
88
|
+
require "lib/og/version"
|
89
|
+
|
90
|
+
PKG_VERSION = $og_version
|
91
|
+
PKG_FILES = FileList[
|
92
|
+
"README.og", "RELEASES.og", "LICENSE", "AUTHORS", "Rakefile", "ChangeLog*",
|
93
|
+
"examples/og/*", "lib/glue.rb", "lib/glue/**/*", "lib/og/**/*", "lib/og.rb",
|
94
|
+
"test/*og*.rb", "test/og/*"
|
95
|
+
].exclude(".svn/**/*").exclude("**/*.log")
|
96
|
+
|
97
|
+
spec = Gem::Specification.new do |s|
|
98
|
+
s.name = 'og'
|
99
|
+
s.version = PKG_VERSION
|
100
|
+
s.summary = 'Og (ObjectGraph)'
|
101
|
+
s.description = 'An efficient and transparent Object-Relational mapping library'
|
102
|
+
# s.add_dependency("postgres", ">= 0.7.1")
|
103
|
+
# s.add_dependency("extensions", ">= 0.5")
|
104
|
+
# s.add_dependency("builder")
|
105
|
+
s.required_ruby_version = ">= 1.8.1"
|
106
|
+
s.files = PKG_FILES.to_a
|
107
|
+
s.require_path = "lib"
|
108
|
+
s.autorequire = "og"
|
109
|
+
s.has_rdoc = true
|
110
|
+
s.extra_rdoc_files = FileList["README.og", "RELEASES.og", "LICENSE", "AUTHORS"].to_a
|
111
|
+
s.rdoc_options << "--main" << "README.og" << "--title" << "Og Documentation"
|
112
|
+
s.test_files = []
|
113
|
+
s.bindir = "bin"
|
114
|
+
s.author = "George Moschovitis"
|
115
|
+
s.email = "gm@navel.gr"
|
116
|
+
s.homepage = "http://www.navel.gr/og"
|
117
|
+
s.rubyforge_project = "og-rml"
|
118
|
+
end
|
119
|
+
|
120
|
+
end
|
121
|
+
|
122
|
+
Rake::GemPackageTask.new(spec) do |pkg|
|
123
|
+
pkg.package_dir = "dist"
|
124
|
+
pkg.need_zip = true
|
125
|
+
pkg.need_tar = true
|
126
|
+
end
|
127
|
+
|
128
|
+
# ----------------------------------------------------------------------
|
129
|
+
|
130
|
+
desc "Install the gem"
|
131
|
+
task :install => :repackage do
|
132
|
+
sh "gem install --local --no-rdoc dist/nitro-#{PKG_VERSION}.gem"
|
133
|
+
end
|
134
|
+
|
135
|
+
# vim: ft=ruby
|
data/examples/og/README
CHANGED
@@ -0,0 +1,58 @@
|
|
1
|
+
# = Og Mocking Example
|
2
|
+
#
|
3
|
+
# A simple example to demonstrate how to mock Og.
|
4
|
+
# Very useful in test units.
|
5
|
+
#
|
6
|
+
# code:
|
7
|
+
# * George Moschovitis <gm@navel.gr>
|
8
|
+
#
|
9
|
+
# (c) 2004 Navel, all rights reserved.
|
10
|
+
# $Id: run.rb 185 2004-12-10 13:29:09Z gmosx $
|
11
|
+
|
12
|
+
$LOAD_PATH.unshift '../../lib'
|
13
|
+
|
14
|
+
require 'rubygems'
|
15
|
+
require 'flexmock'
|
16
|
+
require 'og'
|
17
|
+
require 'og/mock'
|
18
|
+
require 'logger'
|
19
|
+
|
20
|
+
$log = Logger.new($stderr)
|
21
|
+
|
22
|
+
class Article
|
23
|
+
prop_accessor :body, String
|
24
|
+
|
25
|
+
def initialize(body = nil)
|
26
|
+
@body = body
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class SimpleTest < Test::Unit::TestCase
|
31
|
+
|
32
|
+
def setup
|
33
|
+
$og = Og::MockDatabase.new
|
34
|
+
end
|
35
|
+
|
36
|
+
def teardown
|
37
|
+
$og = nil
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_me
|
41
|
+
mocks = [
|
42
|
+
Article.new('body1'),
|
43
|
+
Article.new('body2'),
|
44
|
+
Article.new('body3')
|
45
|
+
]
|
46
|
+
$og.mock_handle(:load_all) { |klass, extrasql| mocks }
|
47
|
+
|
48
|
+
# differnt ways to call the mocked method...
|
49
|
+
puts 'Here are the articles:', Article.all
|
50
|
+
puts 'Here are the articles:', Article.load_all
|
51
|
+
puts 'Here are the articles:', $og.load_all(Article)
|
52
|
+
|
53
|
+
# 3 times called
|
54
|
+
assert_equal(3, $og.mock_count(:load_all))
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
data/examples/og/run.rb
CHANGED
@@ -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
|
9
|
+
# $Id: run.rb 198 2004-12-22 11:26:59Z gmosx $
|
10
10
|
|
11
11
|
$:.unshift "../../lib"
|
12
12
|
|
@@ -103,7 +103,7 @@ class Category
|
|
103
103
|
prop_accessor :body, String
|
104
104
|
|
105
105
|
# define a 'many to many' relation.
|
106
|
-
many_to_many Article
|
106
|
+
many_to_many :articles, Article
|
107
107
|
|
108
108
|
def initialize(title = nil)
|
109
109
|
@title = title
|
@@ -141,7 +141,6 @@ end
|
|
141
141
|
# Initialize a logger.
|
142
142
|
|
143
143
|
$log = Logger.new(STDERR);
|
144
|
-
|
145
144
|
# Og configuration.
|
146
145
|
config = {
|
147
146
|
:address => "localhost",
|
@@ -199,9 +198,11 @@ c2.article_oid = a1.oid
|
|
199
198
|
# managed objects).
|
200
199
|
$og << c2
|
201
200
|
|
201
|
+
# an alternative (easier and cooler) way to add children in a
|
202
|
+
# has_many relation:
|
202
203
|
c3 = ArticleComment.new("Comment 3")
|
203
|
-
|
204
|
-
c3
|
204
|
+
# add_comment is automatically added by Og.
|
205
|
+
a1.add_comment(c3)
|
205
206
|
|
206
207
|
puts "\n\n"
|
207
208
|
puts "* Print all all comments for article 1:"
|
@@ -287,4 +288,7 @@ puts '---'
|
|
287
288
|
|
288
289
|
article.categories.each { |c| puts c.title }
|
289
290
|
|
291
|
+
# create and save the article in one step.
|
292
|
+
article = Article.create("title", "body")
|
290
293
|
|
294
|
+
puts '--', article.oid
|
data/lib/glue/property.rb
CHANGED
@@ -2,10 +2,9 @@
|
|
2
2
|
# * George Moschovitis <gm@navel.gr>
|
3
3
|
# design:
|
4
4
|
# * Anastastios Koutoumanos <ak@navel.gr>
|
5
|
-
# * Elias Karakoulakis <ekarak@ktismata.com>
|
6
5
|
#
|
7
6
|
# (c) 2004 Navel, all rights reserved.
|
8
|
-
# $Id: property.rb
|
7
|
+
# $Id: property.rb 200 2004-12-27 11:24:41Z gmosx $
|
9
8
|
|
10
9
|
require "glue/array"
|
11
10
|
require "glue/hash"
|
@@ -25,10 +24,8 @@ module G
|
|
25
24
|
#
|
26
25
|
#--
|
27
26
|
# TODO:
|
28
|
-
# Inject only the really needd methods into Module.
|
29
27
|
# Perhaps a sync is needed in evals (!!!!)
|
30
28
|
#++
|
31
|
-
#
|
32
29
|
class Property
|
33
30
|
# the symbol of the property
|
34
31
|
attr_accessor :symbol
|
@@ -36,7 +33,7 @@ class Property
|
|
36
33
|
attr_accessor :name
|
37
34
|
# the class of the property
|
38
35
|
attr_accessor :klass
|
39
|
-
# additional metadata (like sql
|
36
|
+
# additional metadata (like sql declaration, sql index, etc)
|
40
37
|
attr_accessor :meta
|
41
38
|
|
42
39
|
def initialize(symbol, klass, meta = {})
|
@@ -52,6 +49,119 @@ class Property
|
|
52
49
|
def to_s
|
53
50
|
return name
|
54
51
|
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
# = PropertyUtils
|
56
|
+
#
|
57
|
+
# A collection of Property related utility methods.
|
58
|
+
#
|
59
|
+
module PropertyUtils
|
60
|
+
|
61
|
+
# Add accessors to the properties to the given target
|
62
|
+
# (Module or Class). For simplicity also create the
|
63
|
+
# meta accessors.
|
64
|
+
#--
|
65
|
+
# gmosx: Perhaps we 'll optimize this in the future.
|
66
|
+
#++
|
67
|
+
def self.enchant(target)
|
68
|
+
unless target.singleton_methods.include?('__props')
|
69
|
+
target.module_eval <<-"end_eval", __FILE__, __LINE__
|
70
|
+
@@__meta = G::SafeHash.new
|
71
|
+
@@__props = G::SafeArray.new
|
72
|
+
|
73
|
+
def self.__props
|
74
|
+
@@__props
|
75
|
+
end
|
76
|
+
|
77
|
+
def self.__props=(props)
|
78
|
+
@@__props = props
|
79
|
+
end
|
80
|
+
|
81
|
+
def self.__meta
|
82
|
+
@@__meta
|
83
|
+
end
|
84
|
+
|
85
|
+
def self.__meta=(meta)
|
86
|
+
@@__meta = meta
|
87
|
+
end
|
88
|
+
end_eval
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
# Copy properties from src (Module or Class) to dest.
|
93
|
+
#
|
94
|
+
def self.copy_props(src, dest)
|
95
|
+
src.__props.each do |p|
|
96
|
+
add_prop(dest, p)
|
97
|
+
end
|
98
|
+
|
99
|
+
# copy the metadata.
|
100
|
+
src.__meta.each do |k, val|
|
101
|
+
val.each { |v| dest.meta(k, v) } if val
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
# Add the property to the target (Class or Module)
|
106
|
+
#
|
107
|
+
def self.add_prop(target, prop)
|
108
|
+
if idx = target.__props.index(prop)
|
109
|
+
# override in case of duplicates. Keep the order of the props.
|
110
|
+
target.__props[idx] = prop
|
111
|
+
else
|
112
|
+
target.__props << prop
|
113
|
+
end
|
114
|
+
|
115
|
+
# Precompile the property read/write methods
|
116
|
+
|
117
|
+
s, klass = prop.symbol, prop.klass
|
118
|
+
|
119
|
+
if prop.meta[:reader]
|
120
|
+
target.module_eval %{
|
121
|
+
def #{s}
|
122
|
+
return @#{s}
|
123
|
+
end
|
124
|
+
}
|
125
|
+
end
|
126
|
+
|
127
|
+
# gmosx: __force_xxx reuses xxx= to allow for easier
|
128
|
+
# overrides.
|
129
|
+
if prop.meta[:writer]
|
130
|
+
target.module_eval %{
|
131
|
+
#{prop_setter(prop)}
|
132
|
+
|
133
|
+
def __force_#{s}(val)
|
134
|
+
self.#{s}=(} + case klass.name
|
135
|
+
when Fixnum.name
|
136
|
+
"val.to_i()"
|
137
|
+
when String.name
|
138
|
+
"val.to_s()"
|
139
|
+
when Float.name
|
140
|
+
"val.to_f()"
|
141
|
+
when Time.name
|
142
|
+
"Time.parse(val.to_s())"
|
143
|
+
when TrueClass.name, FalseClass.name
|
144
|
+
"val.to_i() > 0"
|
145
|
+
else
|
146
|
+
"val"
|
147
|
+
end + %{)
|
148
|
+
end
|
149
|
+
}
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
# Generates the property setter code. Can be overriden
|
154
|
+
# to support extra functionality (example: markup)
|
155
|
+
#
|
156
|
+
def self.prop_setter(prop)
|
157
|
+
s = prop.symbol
|
158
|
+
%{
|
159
|
+
def #{s}=(val)
|
160
|
+
@#{s} = val
|
161
|
+
end
|
162
|
+
}
|
163
|
+
end
|
164
|
+
|
55
165
|
end
|
56
166
|
|
57
167
|
end # module
|
@@ -90,36 +200,55 @@ class Module
|
|
90
200
|
end
|
91
201
|
end
|
92
202
|
|
93
|
-
|
94
|
-
eval %{
|
95
|
-
# Properties
|
96
|
-
# An array is used to enforce order.
|
97
|
-
def __props
|
98
|
-
@__props
|
99
|
-
end
|
203
|
+
G::PropertyUtils.enchant(self)
|
100
204
|
|
101
|
-
|
102
|
-
|
205
|
+
if self.is_a?(Class)
|
206
|
+
|
207
|
+
# Add some extra code to append features to
|
208
|
+
# subclasses.
|
209
|
+
self.module_eval <<-"end_eval", __FILE__, __LINE__
|
210
|
+
|
211
|
+
def self.inherited(sub)
|
212
|
+
G::PropertyUtils.enchant(sub)
|
213
|
+
G::PropertyUtils.copy_props(self, sub)
|
214
|
+
# gmosx: We have to define @@__props first to avoid reusing
|
215
|
+
# the hash from the module. super must stay at the end.
|
216
|
+
super
|
103
217
|
end
|
104
|
-
|
105
|
-
|
106
|
-
|
218
|
+
|
219
|
+
end_eval
|
220
|
+
|
221
|
+
else
|
222
|
+
|
223
|
+
# Add some extra code for modules to append
|
224
|
+
# their features to classes that include it.
|
225
|
+
self.module_eval <<-"end_eval", __FILE__, __LINE__
|
226
|
+
|
227
|
+
def self.append_features(base)
|
228
|
+
G::PropertyUtils.enchant(base)
|
229
|
+
G::PropertyUtils.copy_props(self, base)
|
230
|
+
# gmosx: We have to define @@__props first to avoid reusing
|
231
|
+
# the hash from the module. super must stay at the end.
|
232
|
+
super
|
107
233
|
end
|
108
234
|
|
109
|
-
|
110
|
-
|
111
|
-
end
|
112
|
-
}
|
235
|
+
end_eval
|
236
|
+
|
113
237
|
end
|
114
|
-
|
115
|
-
@__props = G::SafeArray.new() unless @__props
|
116
|
-
|
238
|
+
|
117
239
|
property = G::Property.new(symbol, klass, meta)
|
118
240
|
|
119
241
|
reader = meta[:reader] || true
|
120
242
|
writer = writer || meta[:writer] || false
|
121
|
-
|
122
|
-
|
243
|
+
|
244
|
+
meta[:reader] = true if meta[:reader].nil?
|
245
|
+
if defined?(writer)
|
246
|
+
meta[:writer] = writer
|
247
|
+
else
|
248
|
+
meta[:writer] = true if meta[:writer].nil?
|
249
|
+
end
|
250
|
+
|
251
|
+
G::PropertyUtils.add_prop(self, property)
|
123
252
|
end
|
124
253
|
|
125
254
|
# Helper method. Accepts a collection of symbols and generates
|
@@ -218,90 +347,20 @@ class Module
|
|
218
347
|
end
|
219
348
|
end
|
220
349
|
|
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
350
|
|
271
|
-
# Attach metadata
|
272
|
-
#
|
351
|
+
# Attach metadata.
|
352
|
+
# Guard against duplicates, no need to keep order.
|
353
|
+
# This method uses closures :)
|
354
|
+
#--
|
355
|
+
# gmosx: crappy implementation, recode.
|
356
|
+
#++
|
273
357
|
def meta(key, val)
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
@__meta[key].delete_if { |v| val == v }
|
280
|
-
@__meta[key] << val
|
358
|
+
self.module_eval <<-"end_eval", __FILE__, __LINE__
|
359
|
+
@@__meta[key] ||= []
|
360
|
+
@@__meta[key].delete_if { |v| val == v }
|
361
|
+
@@__meta[key] << val
|
362
|
+
end_eval
|
281
363
|
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
364
|
|
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
365
|
end
|
307
366
|
|