glue 0.0.1 → 0.13.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,83 @@
1
+ # * George Moschovitis <gm@navel.gr>
2
+ # Original code from Rails distribution.
3
+ # http://www.rubyonrails.com
4
+ # $Id$
5
+
6
+ #--
7
+ # Extends the module object with module and instance accessors
8
+ # for class attributes, just like the native attr* accessors for
9
+ # instance attributes. Aliases for classes are also provided.
10
+ #
11
+ # Example:
12
+ #
13
+ # mattr_accessor :my_attr, 'Default value'
14
+ #++
15
+ class Module # :nodoc:
16
+
17
+ def mattr_reader(*params)
18
+ default = if params.last.is_a?(Symbol) then nil else params.pop end
19
+
20
+
21
+ for sym in params
22
+ module_eval <<-"end_eval", __FILE__, __LINE__
23
+
24
+ if not defined?(@@#{sym.id2name})
25
+ @@#{sym.id2name} = #{default.inspect}
26
+ end
27
+
28
+ def self.#{sym.id2name}
29
+ @@#{sym}
30
+ end
31
+
32
+ def #{sym.id2name}
33
+ @@#{sym}
34
+ end
35
+
36
+ def call_#{sym.id2name}
37
+ case @@#{sym.id2name}
38
+ when Symbol then send(@@#{sym})
39
+ when Proc then @@#{sym}.call(self)
40
+ when String then @@#{sym}
41
+ else nil
42
+ end
43
+ end
44
+
45
+ end_eval
46
+ end
47
+ end
48
+ alias_method :cattr_reader, :mattr_reader
49
+
50
+ def mattr_writer(*params)
51
+ default = if params.last.is_a?(Symbol) then nil else params.pop end
52
+
53
+ for sym in params
54
+ module_eval <<-"end_eval", __FILE__, __LINE__
55
+
56
+ if not defined?(@@#{sym.id2name})
57
+ @@#{sym.id2name} = #{default.inspect.inspect}
58
+ end
59
+
60
+ def self.#{sym.id2name}=(obj)
61
+ @@#{sym.id2name} = obj
62
+ end
63
+
64
+ def self.set_#{sym.id2name}(obj)
65
+ @@#{sym.id2name} = obj
66
+ end
67
+
68
+ def #{sym.id2name}=(obj)
69
+ @@#{sym} = obj
70
+ end
71
+
72
+ end_eval
73
+ end
74
+ end
75
+ alias_method :cattr_writer, :cattr_writer
76
+
77
+ def mattr_accessor(*syms)
78
+ mattr_reader(*syms)
79
+ mattr_writer(*syms)
80
+ end
81
+ alias_method :cattr_accessor, :mattr_accessor
82
+
83
+ end
data/lib/glue/cache.rb ADDED
@@ -0,0 +1,138 @@
1
+ # * George Moschovitis <gm@navel.gr>
2
+ # * Anastasios Koutoumanos <ak@navel.gr>
3
+ # (c) 2004-2005 Navel, all rights reserved.
4
+ # $Id: cache.rb 282 2005-03-10 12:24:53Z gmosx $
5
+
6
+ module N
7
+
8
+ # A cache utilizing a simple LRU (Least Recently Used) policy.
9
+ # The items managed by this cache must respond to the #key method.
10
+ # Attempts to optimize reads rather than inserts!
11
+ #
12
+ # LRU semantics are enforced by inserting the items in a queue.
13
+ # The lru item is always at the tail. Two special sentinels
14
+ # (head, tail) are used to simplify (?) the code.
15
+
16
+ class LRUCache < Hash
17
+
18
+ # Mix this in your class to make LRU-managable.
19
+
20
+ module Item
21
+ attr_accessor :lru_key, :lru_prev, :lru_next
22
+ end
23
+
24
+ # head-tail sentinels
25
+
26
+ class Sentinel; include Item; end
27
+
28
+ # the maximum number of items in the cache.
29
+
30
+ attr_accessor :max_items
31
+
32
+ # the head sentinel
33
+
34
+ attr :head
35
+
36
+ # the tail sentinel, tail.prev points to the lru item.
37
+
38
+ attr :tail
39
+
40
+ def initialize(max_items)
41
+ @max_items = max_items
42
+ lru_clear()
43
+ end
44
+
45
+ # Lookup an item in the cache.
46
+
47
+ def [](key)
48
+ if item = super
49
+ return lru_touch(item)
50
+ end
51
+ end
52
+
53
+ # The inserted item is considered mru!
54
+
55
+ def []=(key, item)
56
+ item = super
57
+ item.lru_key = key
58
+ lru_insert(item)
59
+ end
60
+
61
+ # Delete an item from the cache.
62
+
63
+ def delete(key)
64
+ if item = super
65
+ lru_delete(item)
66
+ end
67
+ end
68
+
69
+ # Clear the cache.
70
+
71
+ def clear
72
+ super
73
+ lru_clear()
74
+ end
75
+
76
+ # The first (mru) element in the cache.
77
+
78
+ def first
79
+ @head.lru_next
80
+ end
81
+
82
+ # The last (lru) element in the cache.
83
+
84
+ def last
85
+ @tail.lru_prev
86
+ end
87
+ alias_method :lru, :last
88
+
89
+ private
90
+
91
+ # Delete an item from the lru list.
92
+
93
+ def lru_delete(item)
94
+ lru_join(item.lru_prev, item.lru_next)
95
+ return item
96
+ end
97
+
98
+ # Join two items in the lru list.
99
+ # Return y to allow for chaining.
100
+
101
+ def lru_join(x, y)
102
+ x.lru_next = y
103
+ y.lru_prev = x
104
+ return y
105
+ end
106
+
107
+ # Append a child item to a parent item in the lru list
108
+ # (Re)inserts the child in the list.
109
+
110
+ def lru_append(parent, child)
111
+ lru_join(child, parent.lru_next)
112
+ lru_join(parent, child)
113
+ end
114
+
115
+ # Insert an item
116
+
117
+ def lru_insert(item)
118
+ delete(last.lru_key) if size() > @max_items
119
+ lru_append(@head, item)
120
+ end
121
+
122
+ # Touch an item, make mru!
123
+ # Returns the item.
124
+
125
+ def lru_touch(item)
126
+ lru_append(@head, lru_delete(item))
127
+ end
128
+
129
+ # Clear the lru.
130
+
131
+ def lru_clear
132
+ @head = Sentinel.new
133
+ @tail = Sentinel.new
134
+ lru_join(@head, @tail)
135
+ end
136
+ end
137
+
138
+ end
@@ -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
data/lib/glue/hash.rb ADDED
@@ -0,0 +1,122 @@
1
+ # * George Moschovitis <gm@navel.gr>
2
+ # (c) 2004-2005 Navel, all rights reserved.
3
+ # $Id: hash.rb 282 2005-03-10 12:24:53Z gmosx $
4
+
5
+ require 'sync'
6
+
7
+ module N
8
+
9
+ # A thread-safe hash. We use a sync object instead of a mutex,
10
+ # because it is re-entrant. An exclusive lock is needed when
11
+ # writing, a shared lock IS NEEDED when reading
12
+ # uses the delegator pattern to allow for multiple
13
+ # implementations!
14
+
15
+ class SafeHash < Hash
16
+ attr :sync
17
+
18
+ # gmosx: delegator is not used.
19
+ #
20
+ def initialize(delegator = nil)
21
+ @sync = ::Sync.new
22
+ end
23
+
24
+ def [](key)
25
+ @sync.synchronize(::Sync::SH) { super }
26
+ end
27
+
28
+ def []=(key, value)
29
+ @sync.synchronize(::Sync::EX) { super }
30
+ end
31
+
32
+ def delete(key)
33
+ @sync.synchronize(::Sync::EX) { super }
34
+ end
35
+
36
+ def clear
37
+ @sync.synchronize(::Sync::EX) { super }
38
+ end
39
+
40
+ def size
41
+ @sync.synchronize(::Sync::SH) { super }
42
+ end
43
+
44
+ def values
45
+ @sync.synchronize(::Sync::SH) { super }
46
+ end
47
+
48
+ def keys
49
+ @sync.synchronize(::Sync::SH) { super }
50
+ end
51
+
52
+ end
53
+
54
+ # A thread-safe hash. We use a sync object instead of a mutex,
55
+ # because it is re-entrant. An exclusive lock is needed when
56
+ # writing, a shared lock IS NEEDED when reading.
57
+ #
58
+ # === Design
59
+ #
60
+ # This class uses the delegator pattern. However we dont use rubys
61
+ # delegation facilities, they are more general and powerfull than we
62
+ # need here (and slower). Instead a custom (but simple) solution is
63
+ # used.
64
+ #
65
+ # === Example
66
+ #
67
+ # hash = SafeHashDelegator.new(Hash.new)
68
+ # hash = SafeHashDelegator.new(Hash.new)
69
+
70
+ class SafeHashDelegator < Hash
71
+ attr :delegate, :sync
72
+
73
+ def initialize(delegate)
74
+ @delegate = delegate
75
+ @sync = ::Sync.new
76
+ end
77
+
78
+ def [](key)
79
+ @sync.synchronize(::Sync::SH) {
80
+ @delegate[key]
81
+ }
82
+ end
83
+
84
+ def []=(key, value)
85
+ @sync.synchronize(::Sync::EX) {
86
+ @delegate[key] = value
87
+ }
88
+ end
89
+
90
+ def delete(key)
91
+ @sync.synchronize(::Sync::EX) {
92
+ @delegate.delete(key)
93
+ }
94
+ end
95
+
96
+ def clear
97
+ @sync.synchronize(::Sync::EX) {
98
+ @delegate.clear
99
+ }
100
+ end
101
+
102
+ def size
103
+ @sync.synchronize(::Sync::SH) {
104
+ @delegate.size()
105
+ }
106
+ end
107
+
108
+ def values
109
+ @sync.synchronize(::Sync::SH) {
110
+ @delegate.values()
111
+ }
112
+ end
113
+
114
+ def keys
115
+ @sync.synchronize(::Sync::SH) {
116
+ @delegate.keys()
117
+ }
118
+ end
119
+
120
+ end
121
+
122
+ end
@@ -0,0 +1,91 @@
1
+ # Code from RubyOnRails (http://www.rubyonrails.com)
2
+ # Copyright (c) 2004 David Heinemeier Hansson.
3
+
4
+ module N
5
+
6
+ # The Inflector transforms words from singular to plural,
7
+ # class names to table names, modulized class names to ones without,
8
+ # and class names to foreign keys.
9
+
10
+ module Inflector
11
+ extend self
12
+
13
+ def pluralize(word)
14
+ result = word.dup
15
+ plural_rules.each do |(rule, replacement)|
16
+ break if result.gsub!(rule, replacement)
17
+ end
18
+ return result
19
+ end
20
+
21
+ def singularize(word)
22
+ result = word.dup
23
+ singular_rules.each do |(rule, replacement)|
24
+ break if result.gsub!(rule, replacement)
25
+ end
26
+ return result
27
+ end
28
+
29
+ def camelize(lower_case_and_underscored_word)
30
+ lower_case_and_underscored_word.gsub(/(^|_)(.)/){$2.upcase}
31
+ end
32
+
33
+ def underscore(camel_cased_word)
34
+ camel_cased_word.gsub(/([A-Z]+)([A-Z])/,'\1_\2').gsub(/([a-z])([A-Z])/,'\1_\2').downcase
35
+ end
36
+
37
+ def demodulize(class_name_in_module)
38
+ class_name_in_module.gsub(/^.*::/, '')
39
+ end
40
+
41
+ def foreign_key(class_name, separate_class_name_and_id_with_underscore = true)
42
+ Inflector.underscore(Inflector.demodulize(class_name)) +
43
+ (separate_class_name_and_id_with_underscore ? "_id" : "id")
44
+ end
45
+
46
+ # Convert a class to a name.
47
+
48
+ def name(klass)
49
+ Inflector.underscore(Inflector.demodulize(klass.to_s))
50
+ end
51
+
52
+ # Convert a class to a name in plural
53
+
54
+ def plural_name(klass)
55
+ Inflector.pluralize(Inflector.underscore(Inflector.demodulize(klass.to_s)))
56
+ end
57
+
58
+ private
59
+ def plural_rules #:doc:
60
+ [
61
+ [/(x|ch|ss)$/, '\1es'], # search, switch, fix, box, process, address
62
+ [/([^aeiouy]|qu)y$/, '\1ies'], # query, ability, agency
63
+ [/(?:([^f])fe|([lr])f)$/, '\1\2ves'], # half, safe, wife
64
+ [/sis$/, 'ses'], # basis, diagnosis
65
+ [/([ti])um$/, '\1a'], # datum, medium
66
+ [/person$/, 'people'], # person, salesperson
67
+ [/man$/, 'men'], # man, woman, spokesman
68
+ [/child$/, 'children'], # child
69
+ [/s$/, 's'], # no change (compatibility)
70
+ [/$/, 's']
71
+ ]
72
+ end
73
+
74
+ def singular_rules #:doc:
75
+ [
76
+ [/(x|ch|ss)es$/, '\1'],
77
+ [/([^aeiouy]|qu)ies$/, '\1y'],
78
+ [/([lr])ves$/, '\1f'],
79
+ [/([^f])ves$/, '\1fe'],
80
+ [/(analy|ba|diagno|parenthe|progno|synop|the)ses$/, '\1sis'],
81
+ [/([ti])a$/, '\1um'],
82
+ [/people$/, 'person'],
83
+ [/men$/, 'man'],
84
+ [/status$/, 'status'],
85
+ [/children$/, 'child'],
86
+ [/s$/, '']
87
+ ]
88
+ end
89
+ end
90
+
91
+ end