og 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+