extlib 0.9.6 → 0.9.7
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of extlib might be problematic. Click here for more details.
- data/Rakefile +14 -40
- data/lib/extlib.rb +20 -2
- data/lib/extlib/dictionary.rb +433 -0
- data/lib/extlib/hash.rb +3 -5
- data/lib/extlib/inflection.rb +334 -37
- data/lib/extlib/lazy_array.rb +1 -1
- data/lib/extlib/mash.rb +15 -5
- data/lib/extlib/pooling.rb +36 -27
- data/lib/extlib/string.rb +1 -1
- data/lib/extlib/time.rb +1 -1
- data/lib/extlib/version.rb +1 -1
- metadata +5 -13
data/Rakefile
CHANGED
@@ -46,7 +46,7 @@ spec = Gem::Specification.new do |s|
|
|
46
46
|
s.extra_rdoc_files = ["LICENSE", "README.txt"]
|
47
47
|
|
48
48
|
# Dependencies
|
49
|
-
s.add_dependency "english", ">=0.2.0"
|
49
|
+
# s.add_dependency "english", ">=0.2.0"
|
50
50
|
end
|
51
51
|
|
52
52
|
Rake::GemPackageTask.new(spec) do |package|
|
@@ -126,63 +126,37 @@ namespace :ci do
|
|
126
126
|
out = ENV['CC_BUILD_ARTIFACTS'] || "out"
|
127
127
|
mkdir_p out unless File.directory? out
|
128
128
|
|
129
|
-
mv "ci/
|
130
|
-
mv "ci/
|
131
|
-
mv "ci/integration_rspec_report.html", "#{out}/integration_rspec_report.html"
|
132
|
-
mv "ci/integration_coverage", "#{out}/integration_coverage"
|
129
|
+
mv "ci/rspec_report.html", "#{out}/rspec_report.html"
|
130
|
+
mv "ci/coverage", "#{out}/coverage"
|
133
131
|
mv "ci/doc", "#{out}/doc"
|
134
132
|
mv "ci/cyclomatic", "#{out}/cyclomatic_complexity"
|
135
133
|
mv "ci/token", "#{out}/token_complexity"
|
136
134
|
end
|
137
135
|
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
t.spec_files = Pathname.glob(ROOT + "spec/unit/**/*_spec.rb")
|
142
|
-
unless ENV['NO_RCOV']
|
143
|
-
t.rcov = true
|
144
|
-
t.rcov_opts << '--exclude' << "spec,gems"
|
145
|
-
t.rcov_opts << '--text-summary'
|
146
|
-
t.rcov_opts << '--sort' << 'coverage' << '--sort-reverse'
|
147
|
-
t.rcov_opts << '--only-uncovered'
|
148
|
-
end
|
149
|
-
end
|
150
|
-
|
151
|
-
Spec::Rake::SpecTask.new("spec:integration" => :prepare) do |t|
|
152
|
-
t.spec_opts = ["--format", "specdoc", "--format", "html:#{ROOT}/ci/integration_rspec_report.html", "--diff"]
|
153
|
-
t.spec_files = Pathname.glob(ROOT + "spec/integration/**/*_spec.rb")
|
154
|
-
unless ENV['NO_RCOV']
|
155
|
-
t.rcov = true
|
156
|
-
t.rcov_opts << '--exclude' << "spec,gems"
|
157
|
-
t.rcov_opts << '--text-summary'
|
158
|
-
t.rcov_opts << '--sort' << 'coverage' << '--sort-reverse'
|
159
|
-
t.rcov_opts << '--only-uncovered'
|
160
|
-
end
|
161
|
-
end
|
162
|
-
|
163
|
-
task :spec do
|
164
|
-
Rake::Task["ci:spec:unit"].invoke
|
165
|
-
mv ROOT + "coverage", ROOT + "ci/unit_coverage"
|
166
|
-
|
167
|
-
Rake::Task["ci:spec:integration"].invoke
|
168
|
-
mv ROOT + "coverage", ROOT + "ci/integration_coverage"
|
136
|
+
task :spec => :prepare do
|
137
|
+
Rake::Task[:spec].invoke
|
138
|
+
mv ROOT + "coverage", ROOT + "ci/coverage"
|
169
139
|
end
|
170
140
|
|
171
141
|
task :doc do
|
172
|
-
require '
|
142
|
+
require 'yard'
|
173
143
|
sh 'yardoc'
|
174
144
|
end
|
175
145
|
|
176
|
-
task :saikuro
|
146
|
+
task :saikuro do
|
177
147
|
system "saikuro -c -i lib -y 0 -w 10 -e 15 -o ci/cyclomatic"
|
178
148
|
mv 'ci/cyclomatic/index_cyclo.html', 'ci/cyclomatic/index.html'
|
179
149
|
|
180
150
|
system "saikuro -t -i lib -y 0 -w 20 -e 30 -o ci/token"
|
181
151
|
mv 'ci/token/index_token.html', 'ci/token/index.html'
|
182
152
|
end
|
153
|
+
|
183
154
|
end
|
184
155
|
|
185
|
-
task :ci => ["ci:spec"
|
156
|
+
task :ci => ["ci:spec"]
|
157
|
+
|
158
|
+
desc 'Default: run spec examples'
|
159
|
+
task :default => 'spec'
|
186
160
|
|
187
161
|
##############################################################################
|
188
162
|
# Benchmarks
|
@@ -197,4 +171,4 @@ namespace :benchmark do
|
|
197
171
|
system "ruby #{f}"
|
198
172
|
end
|
199
173
|
end
|
200
|
-
end
|
174
|
+
end
|
data/lib/extlib.rb
CHANGED
@@ -31,8 +31,26 @@ require dir / 'module'
|
|
31
31
|
require dir / 'nil'
|
32
32
|
require dir / 'numeric'
|
33
33
|
require dir / 'blank'
|
34
|
-
require dir / 'pooling'
|
35
34
|
require dir / 'simple_set'
|
36
35
|
require dir / 'struct'
|
37
|
-
require dir / 'hook'
|
38
36
|
require dir / 'symbol'
|
37
|
+
|
38
|
+
Extlib.autoload("Hook", (dir / 'hook').to_s)
|
39
|
+
Extlib.autoload("Pooling", (dir / 'pooling').to_s)
|
40
|
+
|
41
|
+
module Extlib
|
42
|
+
|
43
|
+
def self.exiting= bool
|
44
|
+
if bool && Extlib.const_defined?("Pooling")
|
45
|
+
if Extlib::Pooling.scavenger?
|
46
|
+
Extlib::Pooling.scavenger.wakeup
|
47
|
+
end
|
48
|
+
end
|
49
|
+
@exiting = true
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.exiting
|
53
|
+
@exiting
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
@@ -0,0 +1,433 @@
|
|
1
|
+
# TITLE:
|
2
|
+
#
|
3
|
+
# Dictionary
|
4
|
+
#
|
5
|
+
# AUTHORS:
|
6
|
+
#
|
7
|
+
# - Jan Molic
|
8
|
+
# - Thomas Sawyer
|
9
|
+
#
|
10
|
+
# CREDIT:
|
11
|
+
#
|
12
|
+
# - Andrew Johnson (merge, to_a, inspect, shift and Hash[])
|
13
|
+
# - Jeff Sharpe (reverse and reverse!)
|
14
|
+
# - Thomas Leitner (has_key? and key?)
|
15
|
+
#
|
16
|
+
# LICENSE:
|
17
|
+
#
|
18
|
+
# Copyright (c) 2005 Jan Molic, Thomas Sawyer
|
19
|
+
#
|
20
|
+
# Ruby License
|
21
|
+
#
|
22
|
+
# This module is free software. You may use, modify, and/or redistribute this
|
23
|
+
# software under the same terms as Ruby.
|
24
|
+
#
|
25
|
+
# This program is distributed in the hope that it will be useful, but WITHOUT
|
26
|
+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
27
|
+
# FOR A PARTICULAR PURPOSE.
|
28
|
+
#
|
29
|
+
# Originally ported from OrderHash 2.0, Copyright (c) 2005 jan molic
|
30
|
+
#
|
31
|
+
# LOG:
|
32
|
+
#
|
33
|
+
# - 2007.10.31 trans
|
34
|
+
# Fixed initialize so the constructor blocks correctly effected dictionary
|
35
|
+
# rather then just the internal hash.
|
36
|
+
|
37
|
+
# = Dictionary
|
38
|
+
#
|
39
|
+
# The Dictionary class is a Hash that preserves order.
|
40
|
+
# So it has some array-like extensions also. By defualt
|
41
|
+
# a Dictionary object preserves insertion order, but any
|
42
|
+
# order can be specified including alphabetical key order.
|
43
|
+
#
|
44
|
+
# == Usage
|
45
|
+
#
|
46
|
+
# Just require this file and use Dictionary instead of Hash.
|
47
|
+
#
|
48
|
+
# # You can do simply
|
49
|
+
# hsh = Dictionary.new
|
50
|
+
# hsh['z'] = 1
|
51
|
+
# hsh['a'] = 2
|
52
|
+
# hsh['c'] = 3
|
53
|
+
# p hsh.keys #=> ['z','a','c']
|
54
|
+
#
|
55
|
+
# # or using Dictionary[] method
|
56
|
+
# hsh = Dictionary['z', 1, 'a', 2, 'c', 3]
|
57
|
+
# p hsh.keys #=> ['z','a','c']
|
58
|
+
#
|
59
|
+
# # but this doesn't preserve order
|
60
|
+
# hsh = Dictionary['z'=>1, 'a'=>2, 'c'=>3]
|
61
|
+
# p hsh.keys #=> ['a','c','z']
|
62
|
+
#
|
63
|
+
# # Dictionary has useful extensions: push, pop and unshift
|
64
|
+
# p hsh.push('to_end', 15) #=> true, key added
|
65
|
+
# p hsh.push('to_end', 30) #=> false, already - nothing happen
|
66
|
+
# p hsh.unshift('to_begin', 50) #=> true, key added
|
67
|
+
# p hsh.unshift('to_begin', 60) #=> false, already - nothing happen
|
68
|
+
# p hsh.keys #=> ["to_begin", "a", "c", "z", "to_end"]
|
69
|
+
# p hsh.pop #=> ["to_end", 15], if nothing remains, return nil
|
70
|
+
# p hsh.keys #=> ["to_begin", "a", "c", "z"]
|
71
|
+
# p hsh.shift #=> ["to_begin", 30], if nothing remains, return nil
|
72
|
+
#
|
73
|
+
# == Usage Notes
|
74
|
+
#
|
75
|
+
# * You can use #order_by to set internal sort order.
|
76
|
+
# * #<< takes a two element [k,v] array and inserts.
|
77
|
+
# * Use ::auto which creates Dictionay sub-entries as needed.
|
78
|
+
# * And ::alpha which creates a new Dictionary sorted by key.
|
79
|
+
|
80
|
+
class Dictionary
|
81
|
+
|
82
|
+
include Enumerable
|
83
|
+
|
84
|
+
class << self
|
85
|
+
#--
|
86
|
+
# TODO is this needed? Doesn't the super class do this?
|
87
|
+
#++
|
88
|
+
def [](*args)
|
89
|
+
hsh = new
|
90
|
+
if Hash === args[0]
|
91
|
+
hsh.replace(args[0])
|
92
|
+
elsif (args.size % 2) != 0
|
93
|
+
raise ArgumentError, "odd number of elements for Hash"
|
94
|
+
else
|
95
|
+
while !args.empty?
|
96
|
+
hsh[args.shift] = args.shift
|
97
|
+
end
|
98
|
+
end
|
99
|
+
hsh
|
100
|
+
end
|
101
|
+
|
102
|
+
# Like #new but the block sets the order.
|
103
|
+
#
|
104
|
+
def new_by(*args, &blk)
|
105
|
+
new(*args).order_by(&blk)
|
106
|
+
end
|
107
|
+
|
108
|
+
# Alternate to #new which creates a dictionary sorted by key.
|
109
|
+
#
|
110
|
+
# d = Dictionary.alpha
|
111
|
+
# d["z"] = 1
|
112
|
+
# d["y"] = 2
|
113
|
+
# d["x"] = 3
|
114
|
+
# d #=> {"x"=>3,"y"=>2,"z"=>2}
|
115
|
+
#
|
116
|
+
# This is equivalent to:
|
117
|
+
#
|
118
|
+
# Dictionary.new.order_by { |key,value| key }
|
119
|
+
def alpha(*args, &block)
|
120
|
+
new(*args, &block).order_by_key
|
121
|
+
end
|
122
|
+
|
123
|
+
# Alternate to #new which auto-creates sub-dictionaries as needed.
|
124
|
+
#
|
125
|
+
# d = Dictionary.auto
|
126
|
+
# d["a"]["b"]["c"] = "abc" #=> { "a"=>{"b"=>{"c"=>"abc"}}}
|
127
|
+
#
|
128
|
+
def auto(*args)
|
129
|
+
#AutoDictionary.new(*args)
|
130
|
+
leet = lambda { |hsh, key| hsh[key] = new(&leet) }
|
131
|
+
new(*args, &leet)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
# New Dictiionary.
|
136
|
+
def initialize(*args, &blk)
|
137
|
+
@order = []
|
138
|
+
@order_by = nil
|
139
|
+
if blk
|
140
|
+
dict = self # This ensure autmatic key entry effect the
|
141
|
+
oblk = lambda{ |hsh, key| blk[dict,key] } # dictionary rather then just the interal hash.
|
142
|
+
@hash = Hash.new(*args, &oblk)
|
143
|
+
else
|
144
|
+
@hash = Hash.new(*args)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
def order
|
149
|
+
reorder if @order_by
|
150
|
+
@order
|
151
|
+
end
|
152
|
+
|
153
|
+
# Keep dictionary sorted by a specific sort order.
|
154
|
+
def order_by( &block )
|
155
|
+
@order_by = block
|
156
|
+
order
|
157
|
+
self
|
158
|
+
end
|
159
|
+
|
160
|
+
# Keep dictionary sorted by key.
|
161
|
+
#
|
162
|
+
# d = Dictionary.new.order_by_key
|
163
|
+
# d["z"] = 1
|
164
|
+
# d["y"] = 2
|
165
|
+
# d["x"] = 3
|
166
|
+
# d #=> {"x"=>3,"y"=>2,"z"=>2}
|
167
|
+
#
|
168
|
+
# This is equivalent to:
|
169
|
+
#
|
170
|
+
# Dictionary.new.order_by { |key,value| key }
|
171
|
+
#
|
172
|
+
# The initializer Dictionary#alpha also provides this.
|
173
|
+
def order_by_key
|
174
|
+
@order_by = lambda { |k,v| k }
|
175
|
+
order
|
176
|
+
self
|
177
|
+
end
|
178
|
+
|
179
|
+
# Keep dictionary sorted by value.
|
180
|
+
#
|
181
|
+
# d = Dictionary.new.order_by_value
|
182
|
+
# d["z"] = 1
|
183
|
+
# d["y"] = 2
|
184
|
+
# d["x"] = 3
|
185
|
+
# d #=> {"x"=>3,"y"=>2,"z"=>2}
|
186
|
+
#
|
187
|
+
# This is equivalent to:
|
188
|
+
#
|
189
|
+
# Dictionary.new.order_by { |key,value| value }
|
190
|
+
def order_by_value
|
191
|
+
@order_by = lambda { |k,v| v }
|
192
|
+
order
|
193
|
+
self
|
194
|
+
end
|
195
|
+
|
196
|
+
#
|
197
|
+
def reorder
|
198
|
+
if @order_by
|
199
|
+
assoc = @order.collect{ |k| [k,@hash[k]] }.sort_by(&@order_by)
|
200
|
+
@order = assoc.collect{ |k,v| k }
|
201
|
+
end
|
202
|
+
@order
|
203
|
+
end
|
204
|
+
|
205
|
+
def ==(hsh2)
|
206
|
+
if hsh2.is_a?( Dictionary )
|
207
|
+
@order == hsh2.order &&
|
208
|
+
@hash == hsh2.instance_variable_get("@hash")
|
209
|
+
else
|
210
|
+
false
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
def [] k
|
215
|
+
@hash[ k ]
|
216
|
+
end
|
217
|
+
|
218
|
+
def fetch(k, *a, &b)
|
219
|
+
@hash.fetch(k, *a, &b)
|
220
|
+
end
|
221
|
+
|
222
|
+
# Store operator.
|
223
|
+
#
|
224
|
+
# h[key] = value
|
225
|
+
#
|
226
|
+
# Or with additional index.
|
227
|
+
#
|
228
|
+
# h[key,index] = value
|
229
|
+
def []=(k, i=nil, v=nil)
|
230
|
+
if v
|
231
|
+
insert(i,k,v)
|
232
|
+
else
|
233
|
+
store(k,i)
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
def insert( i,k,v )
|
238
|
+
@order.insert( i,k )
|
239
|
+
@hash.store( k,v )
|
240
|
+
end
|
241
|
+
|
242
|
+
def store( a,b )
|
243
|
+
@order.push( a ) unless @hash.has_key?( a )
|
244
|
+
@hash.store( a,b )
|
245
|
+
end
|
246
|
+
|
247
|
+
def clear
|
248
|
+
@order = []
|
249
|
+
@hash.clear
|
250
|
+
end
|
251
|
+
|
252
|
+
def delete( key )
|
253
|
+
@order.delete( key )
|
254
|
+
@hash.delete( key )
|
255
|
+
end
|
256
|
+
|
257
|
+
def each_key
|
258
|
+
order.each { |k| yield( k ) }
|
259
|
+
self
|
260
|
+
end
|
261
|
+
|
262
|
+
def each_value
|
263
|
+
order.each { |k| yield( @hash[k] ) }
|
264
|
+
self
|
265
|
+
end
|
266
|
+
|
267
|
+
def each
|
268
|
+
order.each { |k| yield( k,@hash[k] ) }
|
269
|
+
self
|
270
|
+
end
|
271
|
+
alias each_pair each
|
272
|
+
|
273
|
+
def delete_if
|
274
|
+
order.clone.each { |k| delete k if yield(k,@hash[k]) }
|
275
|
+
self
|
276
|
+
end
|
277
|
+
|
278
|
+
def values
|
279
|
+
ary = []
|
280
|
+
order.each { |k| ary.push @hash[k] }
|
281
|
+
ary
|
282
|
+
end
|
283
|
+
|
284
|
+
def keys
|
285
|
+
order
|
286
|
+
end
|
287
|
+
|
288
|
+
def invert
|
289
|
+
hsh2 = self.class.new
|
290
|
+
order.each { |k| hsh2[@hash[k]] = k }
|
291
|
+
hsh2
|
292
|
+
end
|
293
|
+
|
294
|
+
def reject( &block )
|
295
|
+
self.dup.delete_if(&block)
|
296
|
+
end
|
297
|
+
|
298
|
+
def reject!( &block )
|
299
|
+
hsh2 = reject(&block)
|
300
|
+
self == hsh2 ? nil : hsh2
|
301
|
+
end
|
302
|
+
|
303
|
+
def replace( hsh2 )
|
304
|
+
@order = hsh2.order
|
305
|
+
@hash = hsh2.hash
|
306
|
+
end
|
307
|
+
|
308
|
+
def shift
|
309
|
+
key = order.first
|
310
|
+
key ? [key,delete(key)] : super
|
311
|
+
end
|
312
|
+
|
313
|
+
def unshift( k,v )
|
314
|
+
unless @hash.include?( k )
|
315
|
+
@order.unshift( k )
|
316
|
+
@hash.store( k,v )
|
317
|
+
true
|
318
|
+
else
|
319
|
+
false
|
320
|
+
end
|
321
|
+
end
|
322
|
+
|
323
|
+
def <<(kv)
|
324
|
+
push( *kv )
|
325
|
+
end
|
326
|
+
|
327
|
+
def push( k,v )
|
328
|
+
unless @hash.include?( k )
|
329
|
+
@order.push( k )
|
330
|
+
@hash.store( k,v )
|
331
|
+
true
|
332
|
+
else
|
333
|
+
false
|
334
|
+
end
|
335
|
+
end
|
336
|
+
|
337
|
+
def pop
|
338
|
+
key = order.last
|
339
|
+
key ? [key,delete(key)] : nil
|
340
|
+
end
|
341
|
+
|
342
|
+
def inspect
|
343
|
+
ary = []
|
344
|
+
each {|k,v| ary << k.inspect + "=>" + v.inspect}
|
345
|
+
'{' + ary.join(", ") + '}'
|
346
|
+
end
|
347
|
+
|
348
|
+
def dup
|
349
|
+
a = []
|
350
|
+
each{ |k,v| a << k; a << v }
|
351
|
+
self.class[*a]
|
352
|
+
end
|
353
|
+
|
354
|
+
def update( hsh2 )
|
355
|
+
hsh2.each { |k,v| self[k] = v }
|
356
|
+
reorder
|
357
|
+
self
|
358
|
+
end
|
359
|
+
alias :merge! update
|
360
|
+
|
361
|
+
def merge( hsh2 )
|
362
|
+
self.dup.update(hsh2)
|
363
|
+
end
|
364
|
+
|
365
|
+
def select
|
366
|
+
ary = []
|
367
|
+
each { |k,v| ary << [k,v] if yield k,v }
|
368
|
+
ary
|
369
|
+
end
|
370
|
+
|
371
|
+
def reverse!
|
372
|
+
@order.reverse!
|
373
|
+
self
|
374
|
+
end
|
375
|
+
|
376
|
+
def reverse
|
377
|
+
dup.reverse!
|
378
|
+
end
|
379
|
+
|
380
|
+
def first
|
381
|
+
@hash[order.first]
|
382
|
+
end
|
383
|
+
|
384
|
+
def last
|
385
|
+
@hash[order.last]
|
386
|
+
end
|
387
|
+
|
388
|
+
def length
|
389
|
+
@order.length
|
390
|
+
end
|
391
|
+
alias :size :length
|
392
|
+
|
393
|
+
def empty?
|
394
|
+
@hash.empty?
|
395
|
+
end
|
396
|
+
|
397
|
+
def has_key?(key)
|
398
|
+
@hash.has_key?(key)
|
399
|
+
end
|
400
|
+
|
401
|
+
def key?(key)
|
402
|
+
@hash.key?(key)
|
403
|
+
end
|
404
|
+
|
405
|
+
def to_a
|
406
|
+
ary = []
|
407
|
+
each { |k,v| ary << [k,v] }
|
408
|
+
ary
|
409
|
+
end
|
410
|
+
|
411
|
+
def to_json
|
412
|
+
buf = "["
|
413
|
+
map do |k,v|
|
414
|
+
buf << k.to_json
|
415
|
+
buf << ", "
|
416
|
+
buf << v.to_json
|
417
|
+
end.join(", ")
|
418
|
+
buf << "]"
|
419
|
+
buf
|
420
|
+
end
|
421
|
+
|
422
|
+
def to_s
|
423
|
+
self.to_a.to_s
|
424
|
+
end
|
425
|
+
|
426
|
+
def to_hash
|
427
|
+
@hash.dup
|
428
|
+
end
|
429
|
+
|
430
|
+
def to_h
|
431
|
+
@hash.dup
|
432
|
+
end
|
433
|
+
end
|
data/lib/extlib/hash.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'base64'
|
2
|
-
|
3
1
|
class Hash
|
4
2
|
class << self
|
5
3
|
# Converts valid XML into a Ruby Hash structure.
|
@@ -162,7 +160,7 @@ class Hash
|
|
162
160
|
# #=> 'one="1" two="TWO"'
|
163
161
|
def to_xml_attributes
|
164
162
|
map do |k,v|
|
165
|
-
%{#{k.to_s.
|
163
|
+
%{#{k.to_s.snake_case.sub(/^(.{1,1})/) { |m| m.downcase }}="#{v}"}
|
166
164
|
end.join(' ')
|
167
165
|
end
|
168
166
|
|
@@ -253,7 +251,7 @@ class REXMLUtilityNode
|
|
253
251
|
self.typecasts["symbol"] = lambda{|v| v.to_sym}
|
254
252
|
self.typecasts["string"] = lambda{|v| v.to_s}
|
255
253
|
self.typecasts["yaml"] = lambda{|v| v.nil? ? nil : YAML.load(v)}
|
256
|
-
self.typecasts["base64Binary"] = lambda{|v|
|
254
|
+
self.typecasts["base64Binary"] = lambda{|v| v.unpack('m').first }
|
257
255
|
|
258
256
|
self.available_typecasts = self.typecasts.keys
|
259
257
|
|
@@ -275,7 +273,7 @@ class REXMLUtilityNode
|
|
275
273
|
|
276
274
|
def to_hash
|
277
275
|
if @type == "file"
|
278
|
-
f = StringIO.new(
|
276
|
+
f = StringIO.new((@children.first || '').unpack('m').first)
|
279
277
|
class << f
|
280
278
|
attr_accessor :original_filename, :content_type
|
281
279
|
end
|
data/lib/extlib/inflection.rb
CHANGED
@@ -1,19 +1,10 @@
|
|
1
|
-
# The original of this file was copied for the ActiveSupport project which is
|
2
|
-
# part of the Ruby On Rails web-framework (http://rubyonrails.org)
|
3
|
-
#
|
4
|
-
# Methods have been modified or removed. English inflection is now provided via
|
5
|
-
# the english gem (http://english.rubyforge.org)
|
6
|
-
#
|
7
|
-
# sudo gem install english
|
8
|
-
#
|
9
|
-
gem 'english', '>=0.2.0'
|
10
|
-
require 'english/inflect'
|
11
|
-
|
12
|
-
English::Inflect.word 'postgres'
|
13
|
-
English::Inflect.singular_word "status", "status"
|
14
|
-
|
15
1
|
module Extlib
|
2
|
+
|
3
|
+
# = English Nouns Number Inflection.
|
4
|
+
#
|
5
|
+
# This module provides english singular <-> plural noun inflections.
|
16
6
|
module Inflection
|
7
|
+
|
17
8
|
class << self
|
18
9
|
# Take an underscored name and make it into a camelized name
|
19
10
|
#
|
@@ -103,36 +94,342 @@ module Extlib
|
|
103
94
|
|
104
95
|
Object.module_eval("::#{$1}", __FILE__, __LINE__)
|
105
96
|
end
|
97
|
+
end
|
98
|
+
|
99
|
+
@singular_of = {}
|
100
|
+
@plural_of = {}
|
106
101
|
|
107
|
-
|
108
|
-
|
102
|
+
@singular_rules = []
|
103
|
+
@plural_rules = []
|
104
|
+
|
105
|
+
class << self
|
106
|
+
# Defines a general inflection exception case.
|
109
107
|
#
|
110
|
-
#
|
111
|
-
#
|
112
|
-
#
|
113
|
-
#
|
114
|
-
#
|
115
|
-
#
|
116
|
-
#
|
108
|
+
# ==== Parameters
|
109
|
+
# singular<String>::
|
110
|
+
# singular form of the word
|
111
|
+
# plural<String>::
|
112
|
+
# plural form of the word
|
113
|
+
#
|
114
|
+
# ==== Examples
|
117
115
|
#
|
118
|
-
|
119
|
-
|
116
|
+
# Here we define erratum/errata exception case:
|
117
|
+
#
|
118
|
+
# English::Inflect.word "erratum", "errata"
|
119
|
+
#
|
120
|
+
# In case singular and plural forms are the same omit
|
121
|
+
# second argument on call:
|
122
|
+
#
|
123
|
+
# English::Inflect.word 'information'
|
124
|
+
def word(singular, plural=nil)
|
125
|
+
plural = singular unless plural
|
126
|
+
singular_word(singular, plural)
|
127
|
+
plural_word(singular, plural)
|
120
128
|
end
|
121
129
|
|
122
|
-
|
130
|
+
def clear(type = :all)
|
131
|
+
if type == :singular || type == :all
|
132
|
+
@singular_of = {}
|
133
|
+
@singular_rules = []
|
134
|
+
@singularization_rules, @singularization_regex = nil, nil
|
135
|
+
end
|
136
|
+
if type == :plural || type == :all
|
137
|
+
@singular_of = {}
|
138
|
+
@singular_rules = []
|
139
|
+
@singularization_rules, @singularization_regex = nil, nil
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
|
144
|
+
# Define a singularization exception.
|
123
145
|
#
|
124
|
-
#
|
125
|
-
#
|
126
|
-
#
|
127
|
-
#
|
128
|
-
#
|
129
|
-
|
130
|
-
|
146
|
+
# ==== Parameters
|
147
|
+
# singular<String>::
|
148
|
+
# singular form of the word
|
149
|
+
# plural<String>::
|
150
|
+
# plural form of the word
|
151
|
+
def singular_word(singular, plural)
|
152
|
+
@singular_of[plural] = singular
|
153
|
+
@singular_of[plural.capitalize] = singular.capitalize
|
154
|
+
end
|
155
|
+
|
156
|
+
# Define a pluralization exception.
|
157
|
+
#
|
158
|
+
# ==== Parameters
|
159
|
+
# singular<String>::
|
160
|
+
# singular form of the word
|
161
|
+
# plural<String>::
|
162
|
+
# plural form of the word
|
163
|
+
def plural_word(singular, plural)
|
164
|
+
@plural_of[singular] = plural
|
165
|
+
@plural_of[singular.capitalize] = plural.capitalize
|
166
|
+
end
|
167
|
+
|
168
|
+
# Define a general rule.
|
169
|
+
#
|
170
|
+
# ==== Parameters
|
171
|
+
# singular<String>::
|
172
|
+
# ending of the word in singular form
|
173
|
+
# plural<String>::
|
174
|
+
# ending of the word in plural form
|
175
|
+
# whole_word<Boolean>::
|
176
|
+
# for capitalization, since words can be
|
177
|
+
# capitalized (Man => Men) #
|
178
|
+
# ==== Examples
|
179
|
+
# Once the following rule is defined:
|
180
|
+
# English::Inflect.rule 'y', 'ies'
|
181
|
+
#
|
182
|
+
# You can see the following results:
|
183
|
+
# irb> "fly".plural
|
184
|
+
# => flies
|
185
|
+
# irb> "cry".plural
|
186
|
+
# => cries
|
187
|
+
# Define a general rule.
|
188
|
+
|
189
|
+
def rule(singular, plural, whole_word = false)
|
190
|
+
singular_rule(singular, plural)
|
191
|
+
plural_rule(singular, plural)
|
192
|
+
word(singular, plural) if whole_word
|
193
|
+
end
|
194
|
+
|
195
|
+
# Define a singularization rule.
|
196
|
+
#
|
197
|
+
# ==== Parameters
|
198
|
+
# singular<String>::
|
199
|
+
# ending of the word in singular form
|
200
|
+
# plural<String>::
|
201
|
+
# ending of the word in plural form
|
202
|
+
#
|
203
|
+
# ==== Examples
|
204
|
+
# Once the following rule is defined:
|
205
|
+
# English::Inflect.singular_rule 'o', 'oes'
|
206
|
+
#
|
207
|
+
# You can see the following results:
|
208
|
+
# irb> "heroes".singular
|
209
|
+
# => hero
|
210
|
+
def singular_rule(singular, plural)
|
211
|
+
@singular_rules << [singular, plural]
|
212
|
+
end
|
213
|
+
|
214
|
+
# Define a plurualization rule.
|
215
|
+
#
|
216
|
+
# ==== Parameters
|
217
|
+
# singular<String>::
|
218
|
+
# ending of the word in singular form
|
219
|
+
# plural<String>::
|
220
|
+
# ending of the word in plural form
|
221
|
+
#
|
222
|
+
# ==== Examples
|
223
|
+
# Once the following rule is defined:
|
224
|
+
# English::Inflect.singular_rule 'fe', 'ves'
|
131
225
|
#
|
132
|
-
|
133
|
-
|
226
|
+
# You can see the following results:
|
227
|
+
# irb> "wife".plural
|
228
|
+
# => wives
|
229
|
+
def plural_rule(singular, plural)
|
230
|
+
@plural_rules << [singular, plural]
|
134
231
|
end
|
135
232
|
|
233
|
+
# Read prepared singularization rules.
|
234
|
+
def singularization_rules
|
235
|
+
if defined?(@singularization_regex) && @singularization_regex
|
236
|
+
return [@singularization_regex, @singularization_hash]
|
237
|
+
end
|
238
|
+
# No sorting needed: Regexen match on longest string
|
239
|
+
@singularization_regex = Regexp.new("(" + @singular_rules.map {|s,p| p}.join("|") + ")$", "i")
|
240
|
+
@singularization_hash = Hash[*@singular_rules.flatten].invert
|
241
|
+
[@singularization_regex, @singularization_hash]
|
242
|
+
end
|
243
|
+
|
244
|
+
# Read prepared pluralization rules.
|
245
|
+
def pluralization_rules
|
246
|
+
if defined?(@pluralization_regex) && @pluralization_regex
|
247
|
+
return [@pluralization_regex, @pluralization_hash]
|
248
|
+
end
|
249
|
+
@pluralization_regex = Regexp.new("(" + @plural_rules.map {|s,p| s}.join("|") + ")$", "i")
|
250
|
+
@pluralization_hash = Hash[*@plural_rules.flatten]
|
251
|
+
[@pluralization_regex, @pluralization_hash]
|
252
|
+
end
|
253
|
+
|
254
|
+
attr_reader :singular_of, :plural_of
|
255
|
+
|
256
|
+
# Convert an English word from plurel to singular.
|
257
|
+
#
|
258
|
+
# "boys".singular #=> boy
|
259
|
+
# "tomatoes".singular #=> tomato
|
260
|
+
#
|
261
|
+
# ==== Parameters
|
262
|
+
# word<String>:: word to singularize
|
263
|
+
#
|
264
|
+
# ==== Returns
|
265
|
+
# <String>:: singularized form of word
|
266
|
+
#
|
267
|
+
# ==== Notes
|
268
|
+
# Aliased as singularize (a Railism)
|
269
|
+
def singular(word)
|
270
|
+
if result = singular_of[word]
|
271
|
+
return result.dup
|
272
|
+
end
|
273
|
+
result = word.dup
|
274
|
+
regex, hash = singularization_rules
|
275
|
+
result.sub!(regex) {|m| hash[m]}
|
276
|
+
singular_of[word] = result
|
277
|
+
return result
|
278
|
+
end
|
279
|
+
|
280
|
+
# Alias for #singular (a Railism).
|
281
|
+
#
|
282
|
+
alias_method(:singularize, :singular)
|
283
|
+
|
284
|
+
# Convert an English word from singular to plurel.
|
285
|
+
#
|
286
|
+
# "boy".plural #=> boys
|
287
|
+
# "tomato".plural #=> tomatoes
|
288
|
+
#
|
289
|
+
# ==== Parameters
|
290
|
+
# word<String>:: word to pluralize
|
291
|
+
#
|
292
|
+
# ==== Returns
|
293
|
+
# <String>:: pluralized form of word
|
294
|
+
#
|
295
|
+
# ==== Notes
|
296
|
+
# Aliased as pluralize (a Railism)
|
297
|
+
def plural(word)
|
298
|
+
# special exceptions
|
299
|
+
return "" if word == ""
|
300
|
+
if result = plural_of[word]
|
301
|
+
return result.dup
|
302
|
+
end
|
303
|
+
result = word.dup
|
304
|
+
regex, hash = pluralization_rules
|
305
|
+
result.sub!(regex) {|m| hash[m]}
|
306
|
+
plural_of[word] = result
|
307
|
+
return result
|
308
|
+
end
|
309
|
+
|
310
|
+
# Alias for #plural (a Railism).
|
311
|
+
alias_method(:pluralize, :plural)
|
136
312
|
end
|
137
|
-
|
138
|
-
|
313
|
+
|
314
|
+
# One argument means singular and plural are the same.
|
315
|
+
|
316
|
+
word 'equipment'
|
317
|
+
word 'information'
|
318
|
+
word 'money'
|
319
|
+
word 'species'
|
320
|
+
word 'series'
|
321
|
+
word 'fish'
|
322
|
+
word 'sheep'
|
323
|
+
word 'moose'
|
324
|
+
word 'hovercraft'
|
325
|
+
word 'grass'
|
326
|
+
word 'rain'
|
327
|
+
word 'milk'
|
328
|
+
word 'rice'
|
329
|
+
word 'plurals'
|
330
|
+
word 'postgres'
|
331
|
+
word 'status'
|
332
|
+
|
333
|
+
# Two arguments defines a singular and plural exception.
|
334
|
+
word 'status' , 'status'
|
335
|
+
word 'Swiss' , 'Swiss'
|
336
|
+
word 'life' , 'lives'
|
337
|
+
word 'wife' , 'wives'
|
338
|
+
word 'goose' , 'geese'
|
339
|
+
word 'criterion' , 'criteria'
|
340
|
+
word 'alias' , 'aliases'
|
341
|
+
word 'status' , 'statuses'
|
342
|
+
word 'axis' , 'axes'
|
343
|
+
word 'crisis' , 'crises'
|
344
|
+
word 'testis' , 'testes'
|
345
|
+
word 'potato' , 'potatoes'
|
346
|
+
word 'tomato' , 'tomatoes'
|
347
|
+
word 'buffalo' , 'buffaloes'
|
348
|
+
word 'torpedo' , 'torpedoes'
|
349
|
+
word 'quiz' , 'quizzes'
|
350
|
+
word 'matrix' , 'matrices'
|
351
|
+
word 'vertex' , 'vertices'
|
352
|
+
word 'index' , 'indices'
|
353
|
+
word 'ox' , 'oxen'
|
354
|
+
word 'mouse' , 'mice'
|
355
|
+
word 'louse' , 'lice'
|
356
|
+
word 'thesis' , 'theses'
|
357
|
+
word 'thief' , 'thieves'
|
358
|
+
word 'analysis' , 'analyses'
|
359
|
+
word 'erratum' , 'errata'
|
360
|
+
word 'phenomenon', 'phenomena'
|
361
|
+
word 'octopus' , 'octopi'
|
362
|
+
word 'thesaurus' , 'thesauri'
|
363
|
+
word 'movie' , 'movies'
|
364
|
+
word 'cactus' , 'cacti'
|
365
|
+
word 'plus' , 'plusses'
|
366
|
+
word 'cross' , 'crosses'
|
367
|
+
word 'medium' , 'media'
|
368
|
+
word 'cow' , 'kine'
|
369
|
+
word 'datum' , 'data'
|
370
|
+
word 'basis' , 'bases'
|
371
|
+
word 'diagnosis' , 'diagnoses'
|
372
|
+
|
373
|
+
# One-way singularization exception (convert plural to singular).
|
374
|
+
|
375
|
+
# General rules.
|
376
|
+
rule 'person' , 'people', true
|
377
|
+
rule 'shoe' , 'shoes', true
|
378
|
+
rule 'hive' , 'hives', true
|
379
|
+
rule 'man' , 'men', true
|
380
|
+
rule 'child' , 'children', true
|
381
|
+
rule 'news' , 'news', true
|
382
|
+
rule 'rf' , 'rves'
|
383
|
+
rule 'af' , 'aves'
|
384
|
+
rule 'ero' , 'eroes'
|
385
|
+
rule 'man' , 'men'
|
386
|
+
rule 'ch' , 'ches'
|
387
|
+
rule 'sh' , 'shes'
|
388
|
+
rule 'ss' , 'sses'
|
389
|
+
rule 'ta' , 'tum'
|
390
|
+
rule 'ia' , 'ium'
|
391
|
+
rule 'ra' , 'rum'
|
392
|
+
rule 'ay' , 'ays'
|
393
|
+
rule 'ey' , 'eys'
|
394
|
+
rule 'oy' , 'oys'
|
395
|
+
rule 'uy' , 'uys'
|
396
|
+
rule 'y' , 'ies'
|
397
|
+
rule 'x' , 'xes'
|
398
|
+
rule 'lf' , 'lves'
|
399
|
+
rule 'ffe' , 'ffes'
|
400
|
+
rule 'afe' , 'aves'
|
401
|
+
rule 'ouse' , 'ouses'
|
402
|
+
# more cases of words ending in -oses not being singularized properly
|
403
|
+
# than cases of words ending in -osis
|
404
|
+
# rule 'osis' , 'oses'
|
405
|
+
rule 'ox' , 'oxes'
|
406
|
+
rule 'us' , 'uses'
|
407
|
+
rule '' , 's'
|
408
|
+
|
409
|
+
# One-way singular rules.
|
410
|
+
|
411
|
+
singular_rule 'of' , 'ofs' # proof
|
412
|
+
singular_rule 'o' , 'oes' # hero, heroes
|
413
|
+
singular_rule 'f' , 'ves'
|
414
|
+
|
415
|
+
# One-way plural rules.
|
416
|
+
|
417
|
+
#plural_rule 'fe' , 'ves' # safe, wife
|
418
|
+
plural_rule 's' , 'ses'
|
419
|
+
plural_rule 'ive' , 'ives' # don't want to snag wife
|
420
|
+
plural_rule 'fe' , 'ves' # don't want to snag perspectives
|
421
|
+
|
422
|
+
|
423
|
+
end
|
424
|
+
end
|
425
|
+
|
426
|
+
class String
|
427
|
+
def singular
|
428
|
+
Extlib::Inflection.singular(self)
|
429
|
+
end
|
430
|
+
alias_method(:singularize, :singular)
|
431
|
+
def plural
|
432
|
+
Extlib::Inflection.plural(self)
|
433
|
+
end
|
434
|
+
alias_method(:pluralize, :plural)
|
435
|
+
end
|
data/lib/extlib/lazy_array.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
class LazyArray # borrowed partially from StrokeDB
|
2
|
-
instance_methods.each { |m| undef_method m unless %w[ __id__ __send__ send dup class object_id kind_of? respond_to? assert_kind_of should should_not instance_variable_set instance_variable_get extend ].include?(m) }
|
2
|
+
instance_methods.each { |m| undef_method m unless %w[ __id__ __send__ send dup class object_id kind_of? respond_to? assert_kind_of should should_not instance_variable_set instance_variable_get extend ].include?(m.to_s) }
|
3
3
|
|
4
4
|
include Enumerable
|
5
5
|
|
data/lib/extlib/mash.rb
CHANGED
@@ -96,6 +96,17 @@ class Mash < Hash
|
|
96
96
|
super(convert_key(key))
|
97
97
|
end
|
98
98
|
|
99
|
+
# @param *rejected<Array[(String, Symbol)] The mash keys to exclude.
|
100
|
+
#
|
101
|
+
# @return <Mash> A new mash without the selected keys.
|
102
|
+
#
|
103
|
+
# @example
|
104
|
+
# { :one => 1, :two => 2, :three => 3 }.except(:one)
|
105
|
+
# #=> { "two" => 2, "three" => 3 }
|
106
|
+
def except(*keys)
|
107
|
+
super(*keys.map {|k| convert_key(k)})
|
108
|
+
end
|
109
|
+
|
99
110
|
# Used to provide the same interface as Hash.
|
100
111
|
#
|
101
112
|
# @return <Mash> This mash unchanged.
|
@@ -126,13 +137,12 @@ class Mash < Hash
|
|
126
137
|
#
|
127
138
|
# @api private
|
128
139
|
def convert_value(value)
|
129
|
-
|
130
|
-
when Hash
|
140
|
+
if value.class == Hash
|
131
141
|
value.to_mash
|
132
|
-
|
142
|
+
elsif value.is_a?(Array)
|
133
143
|
value.collect { |e| convert_value(e) }
|
134
|
-
else
|
135
|
-
value
|
144
|
+
else
|
145
|
+
value
|
136
146
|
end
|
137
147
|
end
|
138
148
|
end
|
data/lib/extlib/pooling.rb
CHANGED
@@ -25,31 +25,43 @@ module Extlib
|
|
25
25
|
# object is reset when it is released.
|
26
26
|
module Pooling
|
27
27
|
|
28
|
+
def self.scavenger?
|
29
|
+
@scavenger && @scavenger.alive?
|
30
|
+
end
|
31
|
+
|
28
32
|
def self.scavenger
|
29
|
-
@scavenger ||
|
33
|
+
if @scavenger.nil? || !@scavenger.alive?
|
30
34
|
@scavenger = Thread.new do
|
31
|
-
|
35
|
+
running = true
|
36
|
+
while running do
|
32
37
|
# Sleep before we actually start doing anything.
|
33
38
|
# Otherwise we might clean up something we just made
|
34
39
|
sleep(scavenger_interval)
|
40
|
+
|
35
41
|
lock.synchronize do
|
36
42
|
pools.each do |pool|
|
37
43
|
# This is a useful check, but non-essential, and right now it breaks lots of stuff.
|
38
44
|
# if pool.expired?
|
39
45
|
pool.lock.synchronize do
|
40
|
-
if pool.
|
46
|
+
if pool.expired?
|
41
47
|
pool.dispose
|
42
48
|
end
|
43
49
|
end
|
44
50
|
# end
|
45
51
|
end
|
52
|
+
|
53
|
+
# The pool is empty, we stop the scavenger
|
54
|
+
# It wil be restarted if new resources are added again
|
55
|
+
if pools.empty?
|
56
|
+
running = false
|
57
|
+
end
|
46
58
|
end
|
47
59
|
end # loop
|
48
60
|
end
|
49
|
-
|
50
|
-
@scavenger.priority = -10
|
51
|
-
@scavenger
|
52
61
|
end
|
62
|
+
|
63
|
+
@scavenger.priority = -10
|
64
|
+
@scavenger
|
53
65
|
end
|
54
66
|
|
55
67
|
def self.pools
|
@@ -79,7 +91,7 @@ module Extlib
|
|
79
91
|
alias __new new
|
80
92
|
end
|
81
93
|
|
82
|
-
@__pools
|
94
|
+
@__pools = {}
|
83
95
|
@__pool_lock = Mutex.new
|
84
96
|
@__pool_wait = ConditionVariable.new
|
85
97
|
|
@@ -92,7 +104,7 @@ module Extlib
|
|
92
104
|
end
|
93
105
|
|
94
106
|
def self.new(*args)
|
95
|
-
@__pools[args].new
|
107
|
+
(@__pools[args] ||= __pool_lock.synchronize { Pool.new(self.pool_size, self, args) }).new
|
96
108
|
end
|
97
109
|
|
98
110
|
def self.__pools
|
@@ -122,7 +134,7 @@ module Extlib
|
|
122
134
|
@args = args
|
123
135
|
|
124
136
|
@available = []
|
125
|
-
@used =
|
137
|
+
@used = {}
|
126
138
|
Extlib::Pooling::append_pool(self)
|
127
139
|
end
|
128
140
|
|
@@ -144,14 +156,14 @@ module Extlib
|
|
144
156
|
lock.synchronize do
|
145
157
|
if @available.size > 0
|
146
158
|
instance = @available.pop
|
147
|
-
@used.
|
159
|
+
@used[instance.object_id] = instance
|
148
160
|
elsif @used.size < @max_size
|
149
161
|
instance = @resource.__new(*@args)
|
150
162
|
raise InvalidResourceError.new("#{@resource} constructor created a nil object") if instance.nil?
|
151
163
|
raise InvalidResourceError.new("#{instance} is already part of the pool") if @used.include? instance
|
152
164
|
instance.instance_variable_set(:@__pool, self)
|
153
165
|
instance.instance_variable_set(:@__allocated_in_pool, Time.now)
|
154
|
-
@used.
|
166
|
+
@used[instance.object_id] = instance
|
155
167
|
else
|
156
168
|
# Let's see whether we have multiple threads
|
157
169
|
# If we do, there is a chance we might be released
|
@@ -171,8 +183,9 @@ module Extlib
|
|
171
183
|
end
|
172
184
|
|
173
185
|
def release(instance)
|
186
|
+
instance.instance_variable_set(:@__allocated_in_pool, Time.now)
|
174
187
|
lock.synchronize do
|
175
|
-
@used.delete
|
188
|
+
@used.delete(instance.object_id)
|
176
189
|
@available.push(instance)
|
177
190
|
wait.signal
|
178
191
|
end
|
@@ -182,7 +195,7 @@ module Extlib
|
|
182
195
|
def delete(instance)
|
183
196
|
lock.synchronize do
|
184
197
|
instance.instance_variable_set(:@__pool, nil)
|
185
|
-
used.delete
|
198
|
+
@used.delete(instance.object_id)
|
186
199
|
end
|
187
200
|
nil
|
188
201
|
end
|
@@ -206,20 +219,16 @@ module Extlib
|
|
206
219
|
!Extlib::Pooling::pools.delete?(self).nil?
|
207
220
|
end
|
208
221
|
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
#
|
220
|
-
# size == 0
|
221
|
-
# end
|
222
|
-
# end
|
222
|
+
def expired?
|
223
|
+
@available.each do |instance|
|
224
|
+
if Extlib.exiting || instance.instance_variable_get(:@__allocated_in_pool) + Extlib::Pooling.scavenger_interval <= Time.now
|
225
|
+
instance.dispose
|
226
|
+
@available.delete(instance)
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
size == 0
|
231
|
+
end
|
223
232
|
|
224
233
|
end
|
225
234
|
|
data/lib/extlib/string.rb
CHANGED
@@ -127,6 +127,6 @@ class String
|
|
127
127
|
# "%s %s %s" % %w(one two three) #=> "one two three"
|
128
128
|
# "%3$s %2$s %1$s" % %w(one two three) #=> "three two one"
|
129
129
|
def t(*values)
|
130
|
-
self.class::translate(self) % values
|
130
|
+
self.class::translate(self) % values.collect! { |value| value.frozen? ? value : self.class::translate(value.to_s) }
|
131
131
|
end
|
132
132
|
end # class String
|
data/lib/extlib/time.rb
CHANGED
data/lib/extlib/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: extlib
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sam Smoot
|
@@ -9,19 +9,10 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-
|
12
|
+
date: 2008-10-06 00:00:00 +03:00
|
13
13
|
default_executable:
|
14
|
-
dependencies:
|
15
|
-
|
16
|
-
name: english
|
17
|
-
type: :runtime
|
18
|
-
version_requirement:
|
19
|
-
version_requirements: !ruby/object:Gem::Requirement
|
20
|
-
requirements:
|
21
|
-
- - ">="
|
22
|
-
- !ruby/object:Gem::Version
|
23
|
-
version: 0.2.0
|
24
|
-
version:
|
14
|
+
dependencies: []
|
15
|
+
|
25
16
|
description: Support library for DataMapper and Merb.
|
26
17
|
email: ssmoot@gmail.com
|
27
18
|
executables: []
|
@@ -41,6 +32,7 @@ files:
|
|
41
32
|
- lib/extlib/boolean.rb
|
42
33
|
- lib/extlib/class.rb
|
43
34
|
- lib/extlib/datetime.rb
|
35
|
+
- lib/extlib/dictionary.rb
|
44
36
|
- lib/extlib/hash.rb
|
45
37
|
- lib/extlib/hook.rb
|
46
38
|
- lib/extlib/inflection.rb
|