glue 0.0.1 → 0.13.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,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