og 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.
@@ -0,0 +1,51 @@
1
+ # = Logger
2
+ #
3
+ # A simple wrapper arround the Ruby logger. Mainly for compatibility
4
+ # purposes.
5
+ #
6
+ # code:
7
+ # * George Moschovitis <gm@navel.gr>
8
+ #
9
+ # (c) 2004 Navel, all rights reserved.
10
+ # $Id: logger.rb 161 2004-11-18 10:51:51Z gmosx $
11
+
12
+ require "logger"
13
+
14
+ # = Logger
15
+ #
16
+ # A simple wrapper arround the Ruby logger. Mainly for compatibility
17
+ # purposes.
18
+ #
19
+ class Logger
20
+ alias_method :devel, :debug
21
+ alias_method :fine, :debug
22
+
23
+ def detach
24
+ end
25
+
26
+ # Used for debuging, remove this in release code.
27
+ #
28
+ def d(str)
29
+ self << "#{str}\n"
30
+ end
31
+
32
+ # Inspect an object. Used for debugging, remove this in release
33
+ # code.
34
+ #
35
+ def i(obj)
36
+ self << "Inspect #{obj.inspect()}\n"
37
+ end
38
+
39
+ private
40
+
41
+ # the default Ruby logger has a hardwired silly format.
42
+ # we use some Ruby magic to fix it!
43
+ remove_const "Format"
44
+
45
+ Format = "%5s: %s\n"
46
+
47
+ def format_message(severity, timestamp, msg, progname)
48
+ Format % [severity, msg]
49
+ end
50
+ end
51
+
@@ -0,0 +1,56 @@
1
+ # = Macros
2
+ #
3
+ # A powerfull macro implementation for Ruby. Allows definition
4
+ # of new macro.
5
+ #
6
+ # EXPERIMENTAL, not fully working yet
7
+ #
8
+ # code:
9
+ # George Moschovitis <gm@navel.gr>
10
+ #
11
+ # (c) 2004 Navel, all rights reserved.
12
+ # $Id: macro.rb 165 2004-11-18 12:04:04Z gmosx $
13
+
14
+ $__macros__ = {}
15
+ $__required__ = {}
16
+
17
+ module Kernel
18
+
19
+ alias_method :old_require, :require
20
+ def require(path)
21
+ return if $__required__[path]
22
+
23
+ source = File.read(path)
24
+
25
+ # parse macro
26
+ source.gsub!(/defmacro\s*\/(.*?)\/\s(.*?)endmacro/m) {
27
+ $__macros__[Regexp.new($1)] = $2 ; ""
28
+ }
29
+
30
+ # expand macros
31
+ $__macros__.each { |match, replace|
32
+ source.gsub!(match, replace)
33
+ }
34
+
35
+ $__required__[path] = true
36
+
37
+ eval(source)
38
+ end
39
+
40
+ end
41
+
42
+ require "nitro/test1.rb"
43
+ require "nitro/test2.rb"
44
+
45
+ __END__
46
+
47
+ Examples:
48
+
49
+ defmacro /my_macro\((.*)\)/
50
+ begin
51
+ my_function(\1)
52
+ rescue => ex
53
+ puts ex
54
+ end
55
+ endmacro
56
+
@@ -0,0 +1,45 @@
1
+ # = Mixins
2
+ #
3
+ # A collection of useful mixins. Use these to synthesize your
4
+ # entities.
5
+ #
6
+ # code:
7
+ # * George Moschovitis <gm@navel.gr>
8
+ #
9
+ # (c) 2004 Navel, all rights reserved.
10
+ # $Id$
11
+
12
+ module G;
13
+
14
+ # = Expirable
15
+ #
16
+ # Generic expiring functionality mixin.
17
+ #
18
+ module Expirable
19
+ attr_accessor :expires
20
+
21
+ # Set the expires timeout for this entry.
22
+
23
+ def expires_after(timeout = (60*60*24))
24
+ @expires = Time.now + timeout
25
+ end
26
+
27
+ # Set the expire timeout for this entry. The timeout happens
28
+ # after (base + rand(spread)) seconds.
29
+
30
+ def expires_spread(base, spread)
31
+ @expires = Time.now + base + rand(spread)
32
+ end
33
+
34
+ # Is this entry expired?
35
+
36
+ def expired?
37
+ if @expires.nil? or (Time.now > @expires)
38
+ return true
39
+ else
40
+ return false
41
+ end
42
+ end
43
+ end
44
+
45
+ end # module
@@ -0,0 +1,30 @@
1
+ # code:
2
+ # * George Moschovitis <gm@navel.gr>
3
+ #
4
+ # (c) 2004 Navel, all rights reserved.
5
+ # $Id: number.rb 167 2004-11-23 14:03:10Z gmosx $
6
+
7
+ module G;
8
+
9
+ # = NumberUtils
10
+ #
11
+ # === Design:
12
+ #
13
+ # Implement as a module to avoid class polution. You can
14
+ # still use Ruby's advanced features to include the module in your
15
+ # class. Passing the object to act upon allows to check for nil,
16
+ # which isn't possible if you use self.
17
+ #
18
+ module NumberUtils
19
+
20
+ # Returns the multiple ceil of a number
21
+ #
22
+ def self.ceil_multiple(num, multiple)
23
+ # gmosx: to_f is needed!s
24
+ # gmosx: IS THERE a more optimized way to do this?
25
+ return ((num.to_f/multiple).ceil*multiple)
26
+ end
27
+
28
+ end
29
+
30
+ end # module
@@ -0,0 +1,63 @@
1
+ # code:
2
+ # * George Moschovitis <gm@navel.gr>
3
+ #
4
+ # (c) 2004 Navel, all rights reserved.
5
+ # $Id: pool.rb 167 2004-11-23 14:03:10Z gmosx $
6
+
7
+ require "thread"
8
+ require "monitor"
9
+
10
+ module G
11
+
12
+ # = Pool
13
+ #
14
+ # Generalized object pool implementation. Implemented as a thread
15
+ # safe stack. Exclusive locking is needed both for push and pop.
16
+ #
17
+ # INVESTIGATE: Could use the SizedQueue/Queue.
18
+ #
19
+ class Pool < Array
20
+ include MonitorMixin
21
+
22
+ def initialize
23
+ super
24
+ @cv = new_cond()
25
+ end
26
+
27
+ # Add, restore an object to the pool.
28
+ #
29
+ def push(obj)
30
+ synchronize do
31
+ super
32
+ @cv.signal()
33
+ end
34
+ end
35
+
36
+ # Obtain an object from the pool.
37
+ #
38
+ def pop
39
+ synchronize do
40
+ @cv.wait_while { empty? }
41
+ super
42
+ end
43
+ end
44
+
45
+ # Obtains an object, passes it to a block for processing
46
+ # and restores it to the pool.
47
+ def obtain
48
+ result = nil
49
+
50
+ begin
51
+ obj = pop()
52
+
53
+ result = yield(obj)
54
+ ensure
55
+ push(obj)
56
+ end
57
+
58
+ return result
59
+ end
60
+
61
+ end
62
+
63
+ end # module
@@ -0,0 +1,301 @@
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 167 2004-11-23 14:03:10Z 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
+ end
52
+
53
+ end # module
54
+
55
+ class Module
56
+
57
+ # Define a property (== typed attribute)
58
+ # This works like Ruby's standard attr method, ie creates
59
+ # only one property.
60
+ #
61
+ # Use the prop_reader, prop_writer, prop_accessor methods
62
+ # for multiple properties.
63
+ #
64
+ # Examples:
65
+ # prop String, :name, :sql => "char(32), :sql_index => "name(32)"
66
+ # --> creates only writer.
67
+ # prop Fixnum, :oid, writer = true, :sql => "integer PRIMARY KEY"
68
+ # --> creates reader and writer.
69
+ #
70
+ def prop(*params)
71
+ meta = {}
72
+ klass = Object
73
+
74
+ for param in params
75
+ if param.is_a?(Class)
76
+ klass = param
77
+ elsif param.is_a?(Symbol)
78
+ symbol = param
79
+ elsif param.is_a?(TrueClass) or param.is_a?(TrueClass)
80
+ writer = param
81
+ elsif param.is_a?(Hash)
82
+ # the meta hash.
83
+ meta = param
84
+ else
85
+ raise "Error when defining property!"
86
+ end
87
+ end
88
+
89
+ unless self.methods.include?("__props")
90
+ eval %{
91
+ # Properties
92
+ # An array is used to enforce order.
93
+ def __props
94
+ @__props
95
+ end
96
+
97
+ def __props=(props)
98
+ @__props = props
99
+ end
100
+
101
+ def __meta
102
+ @__meta
103
+ end
104
+
105
+ def __meta=(meta)
106
+ @__meta = meta
107
+ end
108
+ }
109
+ end
110
+
111
+ @__props = G::SafeArray.new() unless @__props
112
+
113
+ property = G::Property.new(symbol, klass, meta)
114
+
115
+ reader = meta[:reader] || true
116
+ writer = writer || meta[:writer] || false
117
+
118
+ __add_prop(property, reader, writer)
119
+ end
120
+
121
+ # Helper method. Accepts a collection of symbols and generates
122
+ # properties. Only generates reader.
123
+ #
124
+ # Example:
125
+ # prop_reader String, :name, :title, :body, :sql => "char(32)"
126
+ #
127
+ def prop_reader(*params)
128
+ meta = {}
129
+ klass = Object
130
+ symbols = []
131
+
132
+ for param in params
133
+ if param.is_a?(Class)
134
+ klass = param
135
+ elsif param.is_a?(Symbol)
136
+ symbols << param
137
+ elsif param.is_a?(Hash)
138
+ # the meta hash.
139
+ meta = param
140
+ else
141
+ raise "Error when defining property!"
142
+ end
143
+ end
144
+
145
+ meta[:reader] = true
146
+ meta[:writer] = false
147
+
148
+ for symbol in symbols
149
+ prop(klass, symbol, meta)
150
+ end
151
+ end
152
+
153
+ # Helper method. Accepts a collection of symbols and generates
154
+ # properties. Only generates writer.
155
+ #
156
+ # Example:
157
+ # prop_writer String, :name, :title, :body, :sql => "char(32)"
158
+ #
159
+ def prop_writer(*params)
160
+ meta = {}
161
+ klass = Object
162
+ symbols = []
163
+
164
+ for param in params
165
+ if param.is_a?(Class)
166
+ klass = param
167
+ elsif param.is_a?(Symbol)
168
+ symbols << param
169
+ elsif param.is_a?(Hash)
170
+ # the meta hash.
171
+ meta = param
172
+ else
173
+ raise "Error when defining property!"
174
+ end
175
+ end
176
+
177
+ meta[:reader] = false
178
+ meta[:writer] = true
179
+
180
+ for symbol in symbols
181
+ prop(klass, symbol, meta)
182
+ end
183
+ end
184
+
185
+ # Helper method. Accepts a collection of symbols and generates
186
+ # properties. Generates reader and writer.
187
+ #
188
+ # Example:
189
+ # prop_accessor String, :name, :title, :body, :sql => "char(32)"
190
+ #
191
+ def prop_accessor(*params)
192
+ meta = {}
193
+ klass = Object
194
+ symbols = []
195
+
196
+ for param in params
197
+ if param.is_a?(Class)
198
+ klass = param
199
+ elsif param.is_a?(Symbol)
200
+ symbols << param
201
+ elsif param.is_a?(Hash)
202
+ # the meta hash.
203
+ meta = param
204
+ else
205
+ raise "Error when defining property!"
206
+ end
207
+ end
208
+
209
+ meta[:reader] = true
210
+ meta[:writer] = true
211
+
212
+ for symbol in symbols
213
+ prop(klass, symbol, meta)
214
+ end
215
+ end
216
+
217
+ # Add the property
218
+ #
219
+ def __add_prop(prop, reader = true, writer = true)
220
+ if idx = @__props.index(prop)
221
+ # override in case of duplicates. Keep the order of the props.
222
+ @__props[idx] = prop
223
+ else
224
+ @__props << prop
225
+ end
226
+
227
+ # Precompile the property read/write methods
228
+
229
+ s, klass = prop.symbol, prop.klass
230
+
231
+ if reader
232
+ module_eval %{
233
+ def #{s}
234
+ return @#{s}
235
+ end
236
+ }
237
+ end
238
+
239
+ if writer
240
+ module_eval %{
241
+ def #{s}=(val)
242
+ @#{s} = val
243
+ end
244
+
245
+ def __force_#{s}(val)
246
+ @#{s} = } + case klass.name
247
+ when Fixnum.name
248
+ "val.to_i()"
249
+ when String.name
250
+ "val.to_s()"
251
+ when Float.name
252
+ "val.to_f()"
253
+ when Time.name
254
+ "Time.parse(val.to_s())"
255
+ when TrueClass.name, FalseClass.name
256
+ "val.to_i() > 0"
257
+ else
258
+ "val"
259
+ end + %{
260
+ end
261
+ }
262
+ end
263
+ end
264
+
265
+ # Attach metadata
266
+ #
267
+ def meta(key, val)
268
+ @__meta = G::SafeHash.new unless @__meta
269
+
270
+ @__meta[key] = [] unless @__meta[key]
271
+
272
+ # guard against duplicates, no need to keep order.
273
+ @__meta[key].delete_if { |v| val == v }
274
+ @__meta[key] << val
275
+ end
276
+
277
+ # This method is typically called before including other
278
+ # modules to preserve properties order.
279
+ #
280
+ def inherit_meta(mod = superclass)
281
+ # concat props.
282
+ if mod.__props
283
+ @__props = G::SafeArray.new unless @__props
284
+
285
+ mod.__props.each { |p|
286
+ __add_prop(p)
287
+ }
288
+ end
289
+
290
+ # concat metadata
291
+ if mod.__meta
292
+ mod.__meta.each { |k, val|
293
+ val.each { |v|
294
+ meta(k, v)
295
+ } if val
296
+ }
297
+ end
298
+ end
299
+
300
+ end
301
+