extlib 0.9.8 → 0.9.9
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.
Potentially problematic release.
This version of extlib might be problematic. Click here for more details.
- data/History.txt +22 -0
- data/LICENSE +1 -1
- data/README +0 -0
- data/Rakefile +17 -12
- data/lib/extlib.rb +1 -1
- data/lib/extlib/blank.rb +51 -21
- data/lib/extlib/boolean.rb +1 -1
- data/lib/extlib/class.rb +12 -12
- data/lib/extlib/datetime.rb +20 -2
- data/lib/extlib/dictionary.rb +2 -2
- data/lib/extlib/hash.rb +57 -34
- data/lib/extlib/inflection.rb +0 -1
- data/lib/extlib/lazy_array.rb +327 -36
- data/lib/extlib/logger.rb +8 -8
- data/lib/extlib/mash.rb +45 -45
- data/lib/extlib/module.rb +1 -1
- data/lib/extlib/nil.rb +1 -1
- data/lib/extlib/numeric.rb +1 -1
- data/lib/extlib/object.rb +8 -21
- data/lib/extlib/object_space.rb +3 -3
- data/lib/extlib/pathname.rb +10 -0
- data/lib/extlib/pooling.rb +9 -17
- data/lib/extlib/rubygems.rb +7 -7
- data/lib/extlib/simple_set.rb +35 -8
- data/lib/extlib/string.rb +85 -42
- data/lib/extlib/struct.rb +10 -1
- data/lib/extlib/symbol.rb +11 -7
- data/lib/extlib/time.rb +31 -9
- data/lib/extlib/version.rb +1 -1
- data/lib/extlib/virtual_file.rb +1 -1
- data/spec/blank_spec.rb +85 -0
- data/spec/class_spec.rb +141 -0
- data/spec/datetime_spec.rb +22 -0
- data/spec/hash_spec.rb +537 -0
- data/spec/hook_spec.rb +1198 -0
- data/spec/inflection/plural_spec.rb +564 -0
- data/spec/inflection/singular_spec.rb +497 -0
- data/spec/inflection_extras_spec.rb +93 -0
- data/spec/lazy_array_spec.rb +1869 -0
- data/spec/mash_spec.rb +286 -0
- data/spec/module_spec.rb +58 -0
- data/spec/object_space_spec.rb +9 -0
- data/spec/object_spec.rb +114 -0
- data/spec/pooling_spec.rb +499 -0
- data/spec/simple_set_spec.rb +57 -0
- data/spec/spec_helper.rb +7 -0
- data/spec/string_spec.rb +220 -0
- data/spec/struct_spec.rb +12 -0
- data/spec/symbol_spec.rb +8 -0
- data/spec/time_spec.rb +22 -0
- data/spec/try_dup_spec.rb +45 -0
- data/spec/virtual_file_spec.rb +21 -0
- metadata +51 -26
- data/README.txt +0 -3
data/lib/extlib/mash.rb
CHANGED
@@ -9,12 +9,12 @@ class Mash < Hash
|
|
9
9
|
# If constructor is a Hash, a new mash will be created based on the keys of
|
10
10
|
# the hash and no default value will be set.
|
11
11
|
def initialize(constructor = {})
|
12
|
-
if constructor.is_a?(Hash)
|
13
|
-
super()
|
14
|
-
update(constructor)
|
15
|
-
else
|
16
|
-
super(constructor)
|
17
|
-
end
|
12
|
+
if constructor.is_a?(Hash)
|
13
|
+
super()
|
14
|
+
update(constructor)
|
15
|
+
else
|
16
|
+
super(constructor)
|
17
|
+
end
|
18
18
|
end
|
19
19
|
|
20
20
|
# @param key<Object> The default value for the mash. Defaults to nil.
|
@@ -22,15 +22,15 @@ class Mash < Hash
|
|
22
22
|
# @details [Alternatives]
|
23
23
|
# If key is a Symbol and it is a key in the mash, then the default value will
|
24
24
|
# be set to the value matching the key.
|
25
|
-
def default(key = nil)
|
26
|
-
if key.is_a?(Symbol) && include?(key = key.to_s)
|
27
|
-
self[key]
|
28
|
-
else
|
29
|
-
super
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
alias_method :regular_writer, :[]= unless method_defined?(:regular_writer)
|
25
|
+
def default(key = nil)
|
26
|
+
if key.is_a?(Symbol) && include?(key = key.to_s)
|
27
|
+
self[key]
|
28
|
+
else
|
29
|
+
super
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
alias_method :regular_writer, :[]= unless method_defined?(:regular_writer)
|
34
34
|
alias_method :regular_update, :update unless method_defined?(:regular_update)
|
35
35
|
|
36
36
|
# @param key<Object> The key to set.
|
@@ -39,8 +39,8 @@ class Mash < Hash
|
|
39
39
|
#
|
40
40
|
# @see Mash#convert_key
|
41
41
|
# @see Mash#convert_value
|
42
|
-
def []=(key, value)
|
43
|
-
regular_writer(convert_key(key), convert_value(value))
|
42
|
+
def []=(key, value)
|
43
|
+
regular_writer(convert_key(key), convert_value(value))
|
44
44
|
end
|
45
45
|
|
46
46
|
# @param other_hash<Hash>
|
@@ -48,19 +48,19 @@ class Mash < Hash
|
|
48
48
|
# converted to Mash format.
|
49
49
|
#
|
50
50
|
# @return <Mash> The updated mash.
|
51
|
-
def update(other_hash)
|
52
|
-
other_hash.each_pair { |key, value| regular_writer(convert_key(key), convert_value(value)) }
|
53
|
-
self
|
54
|
-
end
|
55
|
-
|
51
|
+
def update(other_hash)
|
52
|
+
other_hash.each_pair { |key, value| regular_writer(convert_key(key), convert_value(value)) }
|
53
|
+
self
|
54
|
+
end
|
55
|
+
|
56
56
|
alias_method :merge!, :update
|
57
57
|
|
58
58
|
# @param key<Object> The key to check for. This will be run through convert_key.
|
59
59
|
#
|
60
60
|
# @return <TrueClass, FalseClass> True if the key exists in the mash.
|
61
|
-
def key?(key)
|
62
|
-
super(convert_key(key))
|
63
|
-
end
|
61
|
+
def key?(key)
|
62
|
+
super(convert_key(key))
|
63
|
+
end
|
64
64
|
|
65
65
|
# def include? def has_key? def member?
|
66
66
|
alias_method :include?, :key?
|
@@ -71,29 +71,29 @@ class Mash < Hash
|
|
71
71
|
# @param *extras<Array> Default value.
|
72
72
|
#
|
73
73
|
# @return <Object> The value at key or the default value.
|
74
|
-
def fetch(key, *extras)
|
75
|
-
super(convert_key(key), *extras)
|
74
|
+
def fetch(key, *extras)
|
75
|
+
super(convert_key(key), *extras)
|
76
76
|
end
|
77
77
|
|
78
78
|
# @param *indices<Array>
|
79
79
|
# The keys to retrieve values for. These will be run through +convert_key+.
|
80
80
|
#
|
81
81
|
# @return <Array> The values at each of the provided keys
|
82
|
-
def values_at(*indices)
|
83
|
-
indices.collect {|key| self[convert_key(key)]}
|
82
|
+
def values_at(*indices)
|
83
|
+
indices.collect {|key| self[convert_key(key)]}
|
84
84
|
end
|
85
85
|
|
86
86
|
# @param hash<Hash> The hash to merge with the mash.
|
87
87
|
#
|
88
88
|
# @return <Mash> A new mash with the hash values merged in.
|
89
|
-
def merge(hash)
|
90
|
-
self.dup.update(hash)
|
89
|
+
def merge(hash)
|
90
|
+
self.dup.update(hash)
|
91
91
|
end
|
92
92
|
|
93
93
|
# @param key<Object>
|
94
94
|
# The key to delete from the mash.\
|
95
|
-
def delete(key)
|
96
|
-
super(convert_key(key))
|
95
|
+
def delete(key)
|
96
|
+
super(convert_key(key))
|
97
97
|
end
|
98
98
|
|
99
99
|
# @param *rejected<Array[(String, Symbol)] The mash keys to exclude.
|
@@ -111,12 +111,12 @@ class Mash < Hash
|
|
111
111
|
#
|
112
112
|
# @return <Mash> This mash unchanged.
|
113
113
|
def stringify_keys!; self end
|
114
|
-
|
114
|
+
|
115
115
|
# @return <Hash> The mash as a Hash with string keys.
|
116
|
-
def to_hash
|
117
|
-
Hash.new(default).merge(self)
|
118
|
-
end
|
119
|
-
|
116
|
+
def to_hash
|
117
|
+
Hash.new(default).merge(self)
|
118
|
+
end
|
119
|
+
|
120
120
|
protected
|
121
121
|
# @param key<Object> The key to convert.
|
122
122
|
#
|
@@ -125,8 +125,8 @@ class Mash < Hash
|
|
125
125
|
# string.
|
126
126
|
#
|
127
127
|
# @api private
|
128
|
-
def convert_key(key)
|
129
|
-
key.kind_of?(Symbol) ? key.to_s : key
|
128
|
+
def convert_key(key)
|
129
|
+
key.kind_of?(Symbol) ? key.to_s : key
|
130
130
|
end
|
131
131
|
|
132
132
|
# @param value<Object> The value to convert.
|
@@ -136,13 +136,13 @@ class Mash < Hash
|
|
136
136
|
# their Mash equivalents.
|
137
137
|
#
|
138
138
|
# @api private
|
139
|
-
def convert_value(value)
|
139
|
+
def convert_value(value)
|
140
140
|
if value.class == Hash
|
141
|
-
value.to_mash
|
141
|
+
value.to_mash
|
142
142
|
elsif value.is_a?(Array)
|
143
|
-
value.collect { |e| convert_value(e) }
|
143
|
+
value.collect { |e| convert_value(e) }
|
144
144
|
else
|
145
145
|
value
|
146
|
-
end
|
146
|
+
end
|
147
147
|
end
|
148
|
-
end
|
148
|
+
end
|
data/lib/extlib/module.rb
CHANGED
data/lib/extlib/nil.rb
CHANGED
data/lib/extlib/numeric.rb
CHANGED
data/lib/extlib/object.rb
CHANGED
@@ -34,10 +34,10 @@ class Object
|
|
34
34
|
# @example
|
35
35
|
# MyString.foo
|
36
36
|
# #=> NoMethodError: undefined method `foo' for MyString:Class
|
37
|
-
# @example
|
37
|
+
# @example
|
38
38
|
# MyString.bar
|
39
39
|
# #=> MyString
|
40
|
-
# @example
|
40
|
+
# @example
|
41
41
|
# String.bar
|
42
42
|
# #=> NoMethodError: undefined method `bar' for String:Class
|
43
43
|
# @example
|
@@ -65,19 +65,19 @@ class Object
|
|
65
65
|
list = name.split("::")
|
66
66
|
list.shift if list.first.blank?
|
67
67
|
obj = self
|
68
|
-
list.each do |x|
|
69
|
-
# This is required because const_get tries to look for constants in the
|
68
|
+
list.each do |x|
|
69
|
+
# This is required because const_get tries to look for constants in the
|
70
70
|
# ancestor chain, but we only want constants that are HERE
|
71
71
|
obj = obj.const_defined?(x) ? obj.const_get(x) : obj.const_missing(x)
|
72
72
|
end
|
73
73
|
obj
|
74
74
|
end
|
75
|
-
|
75
|
+
|
76
76
|
# @param name<String> The name of the constant to get, e.g. "Merb::Router".
|
77
77
|
# @param value<Object> The value to assign to the constant.
|
78
78
|
#
|
79
79
|
# @return <Object> The constant corresponding to the name.
|
80
|
-
def full_const_set(name, value)
|
80
|
+
def full_const_set(name, value)
|
81
81
|
list = name.split("::")
|
82
82
|
toplevel = list.first.blank?
|
83
83
|
list.shift if toplevel
|
@@ -128,14 +128,14 @@ class Object
|
|
128
128
|
false
|
129
129
|
end
|
130
130
|
end
|
131
|
-
|
131
|
+
|
132
132
|
# Override this in a child if it cannot be dup'ed
|
133
133
|
#
|
134
134
|
# @return <Object>
|
135
135
|
def try_dup
|
136
136
|
self.dup
|
137
137
|
end
|
138
|
-
|
138
|
+
|
139
139
|
# @param arrayish<#include?> Container to check, to see if it includes the object.
|
140
140
|
# @param *more<Array>:: additional args, will be flattened into arrayish
|
141
141
|
#
|
@@ -148,19 +148,6 @@ class Object
|
|
148
148
|
arrayish = more.unshift(arrayish) unless more.empty?
|
149
149
|
arrayish.include?(self)
|
150
150
|
end
|
151
|
-
|
152
|
-
# @note
|
153
|
-
# For instances of objects that don't override the #inspect method, there
|
154
|
-
# is an encoded hash to uniquely identify the object. This method
|
155
|
-
# reproduces this to be used in #inspect in order to keep the same look
|
156
|
-
# as well as provide this information.
|
157
|
-
# This is inessential, but may be useful.
|
158
|
-
#
|
159
|
-
# @return <String>
|
160
|
-
# Returns the 16-byte encoded hash for the object
|
161
|
-
def encoded_hash
|
162
|
-
(self.hash * 2).to_s(16)
|
163
|
-
end
|
164
151
|
|
165
152
|
# Add instance_variable_defined? for backward compatibility
|
166
153
|
# @param variable<Symbol, String>
|
data/lib/extlib/object_space.rb
CHANGED
data/lib/extlib/pathname.rb
CHANGED
@@ -1,4 +1,14 @@
|
|
1
1
|
class Pathname
|
2
|
+
# Append path segments and expand to absolute path
|
3
|
+
#
|
4
|
+
# file = Pathname(Dir.pwd) / "subdir1" / :subdir2 / "filename.ext"
|
5
|
+
#
|
6
|
+
# @param [Pathname, String, #to_s] path path segment to concatenate with receiver
|
7
|
+
#
|
8
|
+
# @return [Pathname]
|
9
|
+
# receiver with _path_ appended and expanded to an absolute path
|
10
|
+
#
|
11
|
+
# @api public
|
2
12
|
def /(path)
|
3
13
|
(self + path).expand_path
|
4
14
|
end
|
data/lib/extlib/pooling.rb
CHANGED
@@ -82,9 +82,6 @@ module Extlib
|
|
82
82
|
class InvalidResourceError < StandardError
|
83
83
|
end
|
84
84
|
|
85
|
-
class ThreadStopError < StandardError
|
86
|
-
end
|
87
|
-
|
88
85
|
def self.included(target)
|
89
86
|
target.class_eval do
|
90
87
|
class << self
|
@@ -165,17 +162,12 @@ module Extlib
|
|
165
162
|
instance.instance_variable_set(:@__allocated_in_pool, Time.now)
|
166
163
|
@used[instance.object_id] = instance
|
167
164
|
else
|
168
|
-
#
|
169
|
-
# If we
|
170
|
-
#
|
171
|
-
#
|
172
|
-
#
|
173
|
-
|
174
|
-
if ThreadGroup::Default.list.size <= 2
|
175
|
-
raise ThreadStopError.new(size)
|
176
|
-
else
|
177
|
-
wait.wait(lock)
|
178
|
-
end
|
165
|
+
# Wait for another thread to release an instance.
|
166
|
+
# If we exhaust the pool and don't release the active instance,
|
167
|
+
# we'll wait here forever, so it's *very* important to always
|
168
|
+
# release your services and *never* exhaust the pool within
|
169
|
+
# a single thread.
|
170
|
+
wait.wait(lock)
|
179
171
|
end
|
180
172
|
end
|
181
173
|
end until instance
|
@@ -183,8 +175,8 @@ module Extlib
|
|
183
175
|
end
|
184
176
|
|
185
177
|
def release(instance)
|
186
|
-
instance.instance_variable_set(:@__allocated_in_pool, Time.now)
|
187
178
|
lock.synchronize do
|
179
|
+
instance.instance_variable_set(:@__allocated_in_pool, Time.now)
|
188
180
|
@used.delete(instance.object_id)
|
189
181
|
@available.push(instance)
|
190
182
|
wait.signal
|
@@ -196,6 +188,7 @@ module Extlib
|
|
196
188
|
lock.synchronize do
|
197
189
|
instance.instance_variable_set(:@__pool, nil)
|
198
190
|
@used.delete(instance.object_id)
|
191
|
+
wait.signal
|
199
192
|
end
|
200
193
|
nil
|
201
194
|
end
|
@@ -221,12 +214,11 @@ module Extlib
|
|
221
214
|
|
222
215
|
def expired?
|
223
216
|
@available.each do |instance|
|
224
|
-
if Extlib.exiting || instance.instance_variable_get(:@__allocated_in_pool) + Extlib::Pooling.scavenger_interval <= Time.now
|
217
|
+
if Extlib.exiting || instance.instance_variable_get(:@__allocated_in_pool) + Extlib::Pooling.scavenger_interval <= (Time.now + 0.02)
|
225
218
|
instance.dispose
|
226
219
|
@available.delete(instance)
|
227
220
|
end
|
228
221
|
end
|
229
|
-
|
230
222
|
size == 0
|
231
223
|
end
|
232
224
|
|
data/lib/extlib/rubygems.rb
CHANGED
@@ -2,26 +2,26 @@
|
|
2
2
|
require 'rubygems'
|
3
3
|
module Gem
|
4
4
|
class SourceIndex
|
5
|
-
|
5
|
+
|
6
6
|
# This is resolved in 1.1
|
7
7
|
if Version.new(RubyGemsVersion) < Version.new("1.1")
|
8
|
-
|
8
|
+
|
9
9
|
# Overwrite this so that a gem of the same name and version won't push one
|
10
10
|
# from the gems directory out entirely.
|
11
11
|
#
|
12
12
|
# @param gem_spec<Gem::Specification> The specification of the gem to add.
|
13
13
|
def add_spec(gem_spec)
|
14
14
|
unless gem_spec.instance_variable_get("@loaded_from") &&
|
15
|
-
@gems[gem_spec.full_name].is_a?(Gem::Specification) &&
|
16
|
-
@gems[gem_spec.full_name].installation_path ==
|
15
|
+
@gems[gem_spec.full_name].is_a?(Gem::Specification) &&
|
16
|
+
@gems[gem_spec.full_name].installation_path ==
|
17
17
|
File.join(defined?(Merb) && Merb.respond_to?(:root) ? Merb.root : Dir.pwd,"gems")
|
18
|
-
|
18
|
+
|
19
19
|
@gems[gem_spec.full_name] = gem_spec
|
20
20
|
end
|
21
21
|
end
|
22
|
-
|
22
|
+
|
23
23
|
end
|
24
|
-
|
24
|
+
|
25
25
|
end
|
26
26
|
|
27
27
|
class Specification
|
data/lib/extlib/simple_set.rb
CHANGED
@@ -6,28 +6,55 @@ module Extlib
|
|
6
6
|
# a set of callable actions of controller.
|
7
7
|
class SimpleSet < Hash
|
8
8
|
|
9
|
-
|
9
|
+
##
|
10
|
+
# Create a new SimpleSet containing the unique members of _arr_
|
10
11
|
#
|
11
|
-
# @
|
12
|
+
# @param [Array] arr Initial set values.
|
13
|
+
#
|
14
|
+
# @return [Array] The array the Set was initialized with
|
15
|
+
#
|
16
|
+
# @api public
|
12
17
|
def initialize(arr = [])
|
13
|
-
arr.each {|x| self[x] = true}
|
18
|
+
Array(arr).each {|x| self[x] = true}
|
14
19
|
end
|
15
20
|
|
16
|
-
|
21
|
+
##
|
22
|
+
# Add a value to the set, and return it
|
23
|
+
#
|
24
|
+
# @param [Object] value Value to add to set.
|
17
25
|
#
|
18
|
-
# @return
|
26
|
+
# @return [SimpleSet] Receiver
|
27
|
+
#
|
28
|
+
# @api public
|
19
29
|
def <<(value)
|
20
30
|
self[value] = true
|
31
|
+
self
|
21
32
|
end
|
22
33
|
|
23
|
-
|
34
|
+
##
|
35
|
+
# Merge _arr_ with receiver, producing the union of receiver & _arr_
|
36
|
+
#
|
37
|
+
# s = Extlib::SimpleSet.new([:a, :b, :c])
|
38
|
+
# s.merge([:c, :d, :e, f]) #=> #<SimpleSet: {:e, :c, :f, :a, :d, :b}>
|
24
39
|
#
|
25
|
-
# @
|
40
|
+
# @param [Array] arr Values to merge with set.
|
41
|
+
#
|
42
|
+
# @return [SimpleSet] The set after the Array was merged in.
|
43
|
+
#
|
44
|
+
# @api public
|
26
45
|
def merge(arr)
|
27
46
|
super(arr.inject({}) {|s,x| s[x] = true; s })
|
28
47
|
end
|
29
48
|
|
30
|
-
|
49
|
+
##
|
50
|
+
# Get a human readable version of the set.
|
51
|
+
#
|
52
|
+
# s = SimpleSet.new([:a, :b, :c])
|
53
|
+
# s.inspect #=> "#<SimpleSet: {:c, :a, :b}>"
|
54
|
+
#
|
55
|
+
# @return [String] A human readable version of the set.
|
56
|
+
#
|
57
|
+
# @api public
|
31
58
|
def inspect
|
32
59
|
"#<SimpleSet: {#{keys.map {|x| x.inspect}.join(", ")}}>"
|
33
60
|
end
|