extlib 0.9.10 → 0.9.11
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/History.txt +21 -1
- data/Rakefile +12 -14
- data/lib/extlib.rb +20 -18
- data/lib/extlib/array.rb +36 -0
- data/lib/extlib/byte_array.rb +4 -0
- data/lib/extlib/class.rb +4 -2
- data/lib/extlib/datetime.rb +2 -0
- data/lib/extlib/hash.rb +4 -4
- data/lib/extlib/hook.rb +28 -12
- data/lib/extlib/lazy_array.rb +63 -63
- data/lib/extlib/lazy_module.rb +18 -0
- data/lib/extlib/logger.rb +18 -22
- data/lib/extlib/module.rb +21 -19
- data/lib/extlib/object.rb +14 -1
- data/lib/extlib/pathname.rb +5 -0
- data/lib/extlib/pooling.rb +9 -5
- data/lib/extlib/time.rb +2 -0
- data/lib/extlib/version.rb +1 -1
- data/spec/array_spec.rb +39 -0
- data/spec/byte_array_spec.rb +7 -0
- data/spec/hook_spec.rb +9 -1
- data/spec/lazy_array_spec.rb +1 -0
- data/spec/lazy_module_spec.rb +38 -0
- data/spec/pooling_spec.rb +23 -11
- data/spec/spec.opts +3 -0
- data/spec/spec_helper.rb +1 -2
- data/spec/try_call_spec.rb +73 -0
- metadata +10 -2
data/History.txt
CHANGED
@@ -1,3 +1,23 @@
|
|
1
|
+
=== 0.9.11 / not released
|
2
|
+
|
3
|
+
* 1 major enhancement:
|
4
|
+
|
5
|
+
* Added LazyModule, providing similar capabilities to traits in
|
6
|
+
Smalltalk
|
7
|
+
|
8
|
+
* 5 minor enhancements:
|
9
|
+
|
10
|
+
* Added Array#to_hash and Array#to_mash
|
11
|
+
* Silenced warnings when running in verbose mode
|
12
|
+
* Add ByteArray for representing binary data explicitly
|
13
|
+
* Alias Pathname#to_s to Pathname#to_str when not defined
|
14
|
+
* Added Object#try_call
|
15
|
+
|
16
|
+
* 2 bug fixes:
|
17
|
+
|
18
|
+
* Updated Module.find_const to use const_missing if constant not found
|
19
|
+
* Fixed LazyArray#equal? to compare object_ids
|
20
|
+
|
1
21
|
=== 0.9.10 / 2009-01-19
|
2
22
|
|
3
23
|
* 1 major enhancement:
|
@@ -9,7 +29,7 @@
|
|
9
29
|
* Updated LazyArray#eql? and LazyArray#== to compare without lazy
|
10
30
|
loading if possible.
|
11
31
|
|
12
|
-
3 bug fixes:
|
32
|
+
* 3 bug fixes:
|
13
33
|
|
14
34
|
* Fix for inheritance and hooks
|
15
35
|
* Fix for Class inheritable accessor to use #try_dup
|
data/Rakefile
CHANGED
@@ -9,7 +9,10 @@ require "fileutils"
|
|
9
9
|
require Pathname('spec/rake/spectask')
|
10
10
|
require Pathname('lib/extlib/version')
|
11
11
|
|
12
|
-
ROOT
|
12
|
+
ROOT = Pathname(__FILE__).dirname.expand_path
|
13
|
+
JRUBY = RUBY_PLATFORM =~ /java/
|
14
|
+
WINDOWS = Gem.win_platform?
|
15
|
+
SUDO = (WINDOWS || JRUBY) ? '' : ('sudo' unless ENV['SUDOLESS'])
|
13
16
|
|
14
17
|
##############################################################################
|
15
18
|
# Package && release
|
@@ -26,15 +29,7 @@ GEM_NAME = "extlib"
|
|
26
29
|
PKG_BUILD = ENV['PKG_BUILD'] ? '.' + ENV['PKG_BUILD'] : ''
|
27
30
|
GEM_VERSION = Extlib::VERSION + PKG_BUILD
|
28
31
|
|
29
|
-
RELEASE_NAME
|
30
|
-
|
31
|
-
WINDOWS = (RUBY_PLATFORM =~ /win32|mingw|bccwin|cygwin/) rescue nil
|
32
|
-
JRUBY = (RUBY_PLATFORM =~ /java/) rescue nil
|
33
|
-
|
34
|
-
# sudo is used by default, except on Windows, or if SUDOLESS env is true
|
35
|
-
SUDO = WINDOWS ? '' : ('sudo' unless ENV['SUDOLESS'])
|
36
|
-
# RCov is run by default, except on the JRuby platform, or if NO_RCOV env is true
|
37
|
-
RUN_RCOV = JRUBY ? false : (ENV.has_key?('NO_RCOV') ? ENV['NO_RCOV'] != 'true' : true)
|
32
|
+
RELEASE_NAME = "REL #{GEM_VERSION}"
|
38
33
|
|
39
34
|
require "lib/extlib/tasks/release"
|
40
35
|
|
@@ -73,13 +68,12 @@ task :spec => 'extlib:spec'
|
|
73
68
|
|
74
69
|
namespace :extlib do
|
75
70
|
Spec::Rake::SpecTask.new(:spec) do |t|
|
76
|
-
t.spec_opts << '--
|
77
|
-
t.spec_opts << '--loadby' << 'random'
|
71
|
+
t.spec_opts << '--options' << ROOT + 'spec/spec.opts'
|
78
72
|
t.spec_files = Pathname.glob(ENV['FILES'] || 'spec/**/*_spec.rb').map { |f| f.to_s }
|
79
73
|
|
80
74
|
begin
|
81
75
|
gem 'rcov'
|
82
|
-
t.rcov =
|
76
|
+
t.rcov = JRUBY ? false : (ENV.has_key?('NO_RCOV') ? ENV['NO_RCOV'] != 'true' : true)
|
83
77
|
t.rcov_opts << '--exclude' << 'spec'
|
84
78
|
t.rcov_opts << '--text-summary'
|
85
79
|
t.rcov_opts << '--sort' << 'coverage' << '--sort-reverse'
|
@@ -104,9 +98,13 @@ task :doc do
|
|
104
98
|
end
|
105
99
|
end
|
106
100
|
|
101
|
+
def sudo_gem(cmd)
|
102
|
+
sh "#{SUDO} #{RUBY} -S gem #{cmd}", :verbose => false
|
103
|
+
end
|
104
|
+
|
107
105
|
desc "Install #{GEM_NAME}"
|
108
106
|
task :install => :package do
|
109
|
-
|
107
|
+
sudo_gem "install --local pkg/#{GEM_NAME}-#{GEM_VERSION}"
|
110
108
|
end
|
111
109
|
|
112
110
|
if WINDOWS
|
data/lib/extlib.rb
CHANGED
@@ -1,30 +1,31 @@
|
|
1
1
|
require 'pathname'
|
2
2
|
require 'rubygems'
|
3
3
|
|
4
|
-
|
5
|
-
$LOAD_PATH.unshift(__DIR__) unless $LOAD_PATH.include?(__DIR__)
|
4
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
6
5
|
|
7
6
|
# for Pathname /
|
8
|
-
require File.expand_path(File.join(
|
7
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'extlib', 'pathname'))
|
9
8
|
|
10
9
|
dir = Pathname(__FILE__).dirname.expand_path / 'extlib'
|
11
10
|
|
12
|
-
require dir /
|
13
|
-
require dir /
|
14
|
-
require dir /
|
11
|
+
require dir / 'class.rb'
|
12
|
+
require dir / 'object'
|
13
|
+
require dir / 'object_space'
|
15
14
|
|
16
|
-
require dir /
|
17
|
-
require dir /
|
18
|
-
require dir /
|
19
|
-
require dir /
|
20
|
-
require dir /
|
21
|
-
require dir /
|
22
|
-
require dir /
|
23
|
-
require dir /
|
15
|
+
require dir / 'array'
|
16
|
+
require dir / 'string'
|
17
|
+
require dir / 'symbol'
|
18
|
+
require dir / 'hash'
|
19
|
+
require dir / 'mash'
|
20
|
+
require dir / 'virtual_file'
|
21
|
+
require dir / 'logger'
|
22
|
+
require dir / 'time'
|
23
|
+
require dir / 'datetime'
|
24
24
|
|
25
25
|
require dir / 'assertions'
|
26
26
|
require dir / 'blank'
|
27
27
|
require dir / 'boolean'
|
28
|
+
require dir / 'byte_array'
|
28
29
|
require dir / 'inflection'
|
29
30
|
require dir / 'lazy_array'
|
30
31
|
require dir / 'module'
|
@@ -35,13 +36,13 @@ require dir / 'simple_set'
|
|
35
36
|
require dir / 'struct'
|
36
37
|
require dir / 'symbol'
|
37
38
|
|
38
|
-
Extlib.autoload(
|
39
|
-
Extlib.autoload(
|
39
|
+
Extlib.autoload('Hook', (dir / 'hook').to_s)
|
40
|
+
Extlib.autoload('Pooling', (dir / 'pooling').to_s)
|
40
41
|
|
41
42
|
module Extlib
|
42
43
|
|
43
44
|
def self.exiting= bool
|
44
|
-
if bool && Extlib.const_defined?(
|
45
|
+
if bool && Extlib.const_defined?('Pooling')
|
45
46
|
if Extlib::Pooling.scavenger?
|
46
47
|
Extlib::Pooling.scavenger.wakeup
|
47
48
|
end
|
@@ -50,7 +51,8 @@ module Extlib
|
|
50
51
|
end
|
51
52
|
|
52
53
|
def self.exiting
|
53
|
-
@exiting
|
54
|
+
return @exiting if defined?(@exiting)
|
55
|
+
@exiting = false
|
54
56
|
end
|
55
57
|
|
56
58
|
end
|
data/lib/extlib/array.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
class Array
|
2
|
+
|
3
|
+
##
|
4
|
+
# Transforms an Array of key/value pairs into a Hash
|
5
|
+
#
|
6
|
+
# This is a better idiom than using Hash[*array.flatten] in Ruby 1.8.6
|
7
|
+
# because it is not possible to limit the flattening to a single
|
8
|
+
# level.
|
9
|
+
#
|
10
|
+
# @return [Hash]
|
11
|
+
# A Hash where each entry in the Array is turned into a key/value
|
12
|
+
#
|
13
|
+
# @api public
|
14
|
+
def to_hash
|
15
|
+
h = {}
|
16
|
+
each { |k,v| h[k] = v }
|
17
|
+
h
|
18
|
+
end
|
19
|
+
|
20
|
+
##
|
21
|
+
# Transforms an Array of key/value pairs into a Mash
|
22
|
+
#
|
23
|
+
# This is a better idiom than using Mash[*array.flatten] in Ruby 1.8.6
|
24
|
+
# because it is not possible to limit the flattening to a single
|
25
|
+
# level.
|
26
|
+
#
|
27
|
+
# @return [Mash]
|
28
|
+
# A Hash where each entry in the Array is turned into a key/value
|
29
|
+
#
|
30
|
+
# @api public
|
31
|
+
def to_mash
|
32
|
+
m = Mash.new
|
33
|
+
each { |k,v| m[k] = v }
|
34
|
+
m
|
35
|
+
end
|
36
|
+
end # class Array
|
data/lib/extlib/class.rb
CHANGED
@@ -115,12 +115,14 @@ class Class
|
|
115
115
|
ivars.each do |ivar|
|
116
116
|
self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
117
117
|
def self.#{ivar}
|
118
|
-
return @#{ivar} if
|
118
|
+
return @#{ivar} if defined?(@#{ivar})
|
119
|
+
return nil if self.object_id == #{self.object_id}
|
119
120
|
ivar = superclass.#{ivar}
|
120
|
-
return nil if ivar.nil?
|
121
|
+
return nil if ivar.nil?
|
121
122
|
@#{ivar} = ivar.try_dup
|
122
123
|
end
|
123
124
|
RUBY
|
125
|
+
|
124
126
|
unless instance_reader == false
|
125
127
|
self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
126
128
|
def #{ivar}
|
data/lib/extlib/datetime.rb
CHANGED
@@ -9,6 +9,7 @@ class DateTime
|
|
9
9
|
# @return [Time] Time object representing the same moment as receiver
|
10
10
|
#
|
11
11
|
# @api public
|
12
|
+
remove_method :to_time if method_defined?(:to_time) || private_method_defined?(:to_time)
|
12
13
|
def to_time
|
13
14
|
Time.parse self.to_s
|
14
15
|
end
|
@@ -21,6 +22,7 @@ class DateTime
|
|
21
22
|
# @return [DateTime] Receiver
|
22
23
|
#
|
23
24
|
# @api public
|
25
|
+
remove_method :to_datetime if method_defined?(:to_datetime) || private_method_defined?(:to_datetime)
|
24
26
|
def to_datetime
|
25
27
|
self
|
26
28
|
end
|
data/lib/extlib/hash.rb
CHANGED
@@ -131,11 +131,11 @@ class Hash
|
|
131
131
|
end
|
132
132
|
|
133
133
|
stack.each do |parent, hash|
|
134
|
-
hash.each do |
|
135
|
-
if
|
136
|
-
stack << ["#{parent}[#{
|
134
|
+
hash.each do |k, v|
|
135
|
+
if v.is_a?(Hash)
|
136
|
+
stack << ["#{parent}[#{k}]", v]
|
137
137
|
else
|
138
|
-
param << normalize_param("#{parent}[#{
|
138
|
+
param << normalize_param("#{parent}[#{k}]", v)
|
139
139
|
end
|
140
140
|
end
|
141
141
|
end
|
data/lib/extlib/hook.rb
CHANGED
@@ -235,21 +235,26 @@ module Extlib
|
|
235
235
|
after_hooks = hooks[target_method][:after]
|
236
236
|
after_hooks = after_hooks.map{ |info| inline_call(info, scope) }.join("\n")
|
237
237
|
|
238
|
-
|
238
|
+
before_hook_name = hook_method_name(target_method, 'execute_before', 'hook_stack')
|
239
|
+
after_hook_name = hook_method_name(target_method, 'execute_after', 'hook_stack')
|
240
|
+
|
241
|
+
hooks[target_method][:in].class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
242
|
+
#{scope == :class ? 'class << self' : ''}
|
243
|
+
|
239
244
|
private
|
240
245
|
|
241
|
-
|
246
|
+
remove_method :#{before_hook_name} if method_defined?(:#{before_hook_name}) || private_method_defined?(:#{before_hook_name})
|
247
|
+
def #{before_hook_name}(*args)
|
242
248
|
#{before_hooks}
|
243
249
|
end
|
244
250
|
|
245
|
-
|
251
|
+
remove_method :#{after_hook_name} if method_defined?(:#{after_hook_name}) || private_method_defined?(:#{after_hook_name})
|
252
|
+
def #{after_hook_name}(*args)
|
246
253
|
#{after_hooks}
|
247
254
|
end
|
248
|
-
}
|
249
255
|
|
250
|
-
|
251
|
-
|
252
|
-
hooks[target_method][:in].class_eval(source, __FILE__, __LINE__ - 12)
|
256
|
+
#{scope == :class ? 'end' : ''}
|
257
|
+
RUBY
|
253
258
|
end
|
254
259
|
|
255
260
|
# Returns ruby code that will invoke the hook. It checks the arity of the hook method
|
@@ -321,14 +326,25 @@ module Extlib
|
|
321
326
|
#if this hook is previously declared in a sibling or cousin we must move the :in class
|
322
327
|
#to the common ancestor to get both hooks to run.
|
323
328
|
if !(hooks[target_method][:in] <=> self)
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
+
before_hook_name = hook_method_name(target_method, 'execute_before', 'hook_stack')
|
330
|
+
after_hook_name = hook_method_name(target_method, 'execute_after', 'hook_stack')
|
331
|
+
|
332
|
+
hooks[target_method][:in].class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
333
|
+
remove_method :#{before_hook_name} if method_defined?(:#{before_hook_name}) || private_method_defined?(:#{before_hook_name})
|
334
|
+
def #{before_hook_name}(*args)
|
335
|
+
super
|
336
|
+
end
|
337
|
+
|
338
|
+
remove_method :#{after_hook_name} if method_defined?(:#{after_hook_name}) || private_method_defined?(:#{after_hook_name})
|
339
|
+
def #{after_hook_name}(*args)
|
340
|
+
super
|
341
|
+
end
|
342
|
+
RUBY
|
343
|
+
|
329
344
|
while !(hooks[target_method][:in] <=> self) do
|
330
345
|
hooks[target_method][:in] = hooks[target_method][:in].superclass
|
331
346
|
end
|
347
|
+
|
332
348
|
define_hook_stack_execution_methods(target_method, scope)
|
333
349
|
hooks[target_method][:in].class_eval{define_advised_method(target_method, scope)}
|
334
350
|
end
|
data/lib/extlib/lazy_array.rb
CHANGED
@@ -1,17 +1,6 @@
|
|
1
1
|
class LazyArray # borrowed partially from StrokeDB
|
2
2
|
instance_methods.each { |m| undef_method m unless %w[ __id__ __send__ send class dup object_id kind_of? respond_to? equal? assert_kind_of should should_not instance_variable_set instance_variable_get extend ].include?(m.to_s) }
|
3
3
|
|
4
|
-
# add proxies for all Array and Enumerable methods
|
5
|
-
((Array.instance_methods(false) | Enumerable.instance_methods(false)).map { |m| m.to_s } - %w[ taguri= ]).each do |method|
|
6
|
-
class_eval <<-EOS, __FILE__, __LINE__
|
7
|
-
def #{method}(*args, &block)
|
8
|
-
lazy_load
|
9
|
-
results = @array.#{method}(*args, &block)
|
10
|
-
results.equal?(@array) ? self : results
|
11
|
-
end
|
12
|
-
EOS
|
13
|
-
end
|
14
|
-
|
15
4
|
def first(*args)
|
16
5
|
if lazy_possible?(@head, *args)
|
17
6
|
@head.first(*args)
|
@@ -60,7 +49,7 @@ class LazyArray # borrowed partially from StrokeDB
|
|
60
49
|
lazy_possible = args.all? do |arg|
|
61
50
|
index, length = extract_slice_arguments(arg)
|
62
51
|
|
63
|
-
if index >= 0 && lazy_possible?(@head, index +
|
52
|
+
if index >= 0 && lazy_possible?(@head, index + length)
|
64
53
|
accumulator.concat(head.values_at(*arg))
|
65
54
|
elsif index < 0 && lazy_possible?(@tail, index.abs)
|
66
55
|
accumulator.concat(tail.values_at(*arg))
|
@@ -105,12 +94,10 @@ class LazyArray # borrowed partially from StrokeDB
|
|
105
94
|
def [](*args)
|
106
95
|
index, length = extract_slice_arguments(*args)
|
107
96
|
|
108
|
-
if length.
|
97
|
+
if length == 1 && args.size == 1 && args.first.kind_of?(Integer)
|
109
98
|
return at(index)
|
110
99
|
end
|
111
100
|
|
112
|
-
length ||= 1
|
113
|
-
|
114
101
|
if index >= 0 && lazy_possible?(@head, index + length)
|
115
102
|
@head[*args]
|
116
103
|
elsif index < 0 && lazy_possible?(@tail, index.abs - 1 + length)
|
@@ -126,8 +113,6 @@ class LazyArray # borrowed partially from StrokeDB
|
|
126
113
|
def slice!(*args)
|
127
114
|
index, length = extract_slice_arguments(*args)
|
128
115
|
|
129
|
-
length ||= 1
|
130
|
-
|
131
116
|
if index >= 0 && lazy_possible?(@head, index + length)
|
132
117
|
@head.slice!(*args)
|
133
118
|
elsif index < 0 && lazy_possible?(@tail, index.abs - 1 + length)
|
@@ -141,8 +126,6 @@ class LazyArray # borrowed partially from StrokeDB
|
|
141
126
|
def []=(*args)
|
142
127
|
index, length = extract_slice_arguments(*args[0..-2])
|
143
128
|
|
144
|
-
length ||= 1
|
145
|
-
|
146
129
|
if index >= 0 && lazy_possible?(@head, index + length)
|
147
130
|
@head.[]=(*args)
|
148
131
|
elsif index < 0 && lazy_possible?(@tail, index.abs - 1 + length)
|
@@ -265,7 +248,6 @@ class LazyArray # borrowed partially from StrokeDB
|
|
265
248
|
lazy_load
|
266
249
|
@array.delete_if(&block)
|
267
250
|
else
|
268
|
-
@reapers ||= []
|
269
251
|
@reapers << block
|
270
252
|
@head.delete_if(&block)
|
271
253
|
@tail.delete_if(&block)
|
@@ -326,58 +308,31 @@ class LazyArray # borrowed partially from StrokeDB
|
|
326
308
|
@frozen == true
|
327
309
|
end
|
328
310
|
|
329
|
-
def
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
unless loaded?
|
334
|
-
# compare the head against the beginning of other. start at index
|
335
|
-
# 0 and incrementally compare each entry. if other is a LazyArray
|
336
|
-
# this has a lesser likelyhood of triggering a lazy load
|
337
|
-
0.upto(@head.size - 1) do |i|
|
338
|
-
return false unless @head[i].eql?(other[i])
|
339
|
-
end
|
340
|
-
|
341
|
-
# compare the tail against the end of other. start at index
|
342
|
-
# -1 and decrementally compare each entry. if other is a LazyArray
|
343
|
-
# this has a lesser likelyhood of triggering a lazy load
|
344
|
-
-1.downto(@tail.size * -1) do |i|
|
345
|
-
return false unless @tail[i].eql?(other[i])
|
346
|
-
end
|
347
|
-
|
348
|
-
lazy_load
|
311
|
+
def ==(other)
|
312
|
+
if equal?(other)
|
313
|
+
return true
|
349
314
|
end
|
350
315
|
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
def ==(other)
|
356
|
-
return true if equal?(other)
|
357
|
-
return false unless other.respond_to?(:to_ary)
|
316
|
+
unless other.respond_to?(:to_ary)
|
317
|
+
return false
|
318
|
+
end
|
358
319
|
|
359
320
|
# if necessary, convert to something that can be compared
|
360
321
|
other = other.to_ary unless other.respond_to?(:[])
|
361
322
|
|
362
|
-
|
363
|
-
|
364
|
-
# 0 and incrementally compare each entry. if other is a LazyArray
|
365
|
-
# this has a lesser likelyhood of triggering a lazy load
|
366
|
-
0.upto(@head.size - 1) do |i|
|
367
|
-
return false unless @head[i] == other[i]
|
368
|
-
end
|
323
|
+
cmp?(other, :==)
|
324
|
+
end
|
369
325
|
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
return false unless @tail[i] == other[i]
|
375
|
-
end
|
326
|
+
def eql?(other)
|
327
|
+
if equal?(other)
|
328
|
+
return true
|
329
|
+
end
|
376
330
|
|
377
|
-
|
331
|
+
unless other.class.equal?(self.class)
|
332
|
+
return false
|
378
333
|
end
|
379
334
|
|
380
|
-
|
335
|
+
cmp?(other, :eql?)
|
381
336
|
end
|
382
337
|
|
383
338
|
protected
|
@@ -391,10 +346,13 @@ class LazyArray # borrowed partially from StrokeDB
|
|
391
346
|
private
|
392
347
|
|
393
348
|
def initialize
|
349
|
+
@frozen = false
|
350
|
+
@loaded = false
|
394
351
|
@load_with_proc = lambda { |v| v }
|
395
352
|
@head = []
|
396
353
|
@tail = []
|
397
354
|
@array = []
|
355
|
+
@reapers = []
|
398
356
|
end
|
399
357
|
|
400
358
|
def initialize_copy(original)
|
@@ -441,7 +399,7 @@ class LazyArray # borrowed partially from StrokeDB
|
|
441
399
|
return first_arg, second_arg
|
442
400
|
elsif args.size == 1
|
443
401
|
if first_arg.kind_of?(Integer)
|
444
|
-
return first_arg
|
402
|
+
return first_arg, 1
|
445
403
|
elsif first_arg.kind_of?(Range)
|
446
404
|
index = first_arg.first
|
447
405
|
length = first_arg.last - index
|
@@ -464,4 +422,46 @@ class LazyArray # borrowed partially from StrokeDB
|
|
464
422
|
super
|
465
423
|
end
|
466
424
|
end
|
425
|
+
|
426
|
+
def cmp?(other, operator)
|
427
|
+
unless loaded?
|
428
|
+
# compare the head against the beginning of other. start at index
|
429
|
+
# 0 and incrementally compare each entry. if other is a LazyArray
|
430
|
+
# this has a lesser likelyhood of triggering a lazy load
|
431
|
+
0.upto(@head.size - 1) do |i|
|
432
|
+
return false unless @head[i].send(operator, other[i])
|
433
|
+
end
|
434
|
+
|
435
|
+
# compare the tail against the end of other. start at index
|
436
|
+
# -1 and decrementally compare each entry. if other is a LazyArray
|
437
|
+
# this has a lesser likelyhood of triggering a lazy load
|
438
|
+
-1.downto(@tail.size * -1) do |i|
|
439
|
+
return false unless @tail[i].send(operator, other[i])
|
440
|
+
end
|
441
|
+
|
442
|
+
lazy_load
|
443
|
+
end
|
444
|
+
|
445
|
+
@array.send(operator, other.to_ary)
|
446
|
+
end
|
447
|
+
|
448
|
+
# add proxies for all remaining Array and Enumerable methods
|
449
|
+
(Array.public_instance_methods(false) | Enumerable.public_instance_methods(false)).each do |method|
|
450
|
+
next if public_method_defined?(method)
|
451
|
+
|
452
|
+
target = if method.to_s[-1, 1] == '='
|
453
|
+
"send(:#{method}, *args, &block)"
|
454
|
+
else
|
455
|
+
"#{method}(*args, &block)"
|
456
|
+
end
|
457
|
+
|
458
|
+
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
459
|
+
public
|
460
|
+
def #{method}(*args, &block) # def []=(*args, &block)
|
461
|
+
lazy_load # lazy_load
|
462
|
+
results = @array.#{target} # results = @array.send(:[]=, *args, &block)
|
463
|
+
results.equal?(@array) ? self : results # results.equal?(@array) ? self : results
|
464
|
+
end # end
|
465
|
+
RUBY
|
466
|
+
end
|
467
467
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class LazyModule < Module
|
2
|
+
def self.new(&blk)
|
3
|
+
# passing no-op block overrides &blk
|
4
|
+
m = super{ }
|
5
|
+
class << m
|
6
|
+
include ClassMethods
|
7
|
+
end
|
8
|
+
m.lazy_evaluated_body = blk
|
9
|
+
m
|
10
|
+
end
|
11
|
+
|
12
|
+
module ClassMethods
|
13
|
+
attr_accessor :lazy_evaluated_body
|
14
|
+
def included(host)
|
15
|
+
host.class_eval(&@lazy_evaluated_body)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/extlib/logger.rb
CHANGED
@@ -1,36 +1,36 @@
|
|
1
1
|
require "time" # httpdate
|
2
|
-
# ==== Public
|
2
|
+
# ==== Public Extlib Logger API
|
3
3
|
#
|
4
4
|
# To replace an existing logger with a new one:
|
5
|
-
#
|
5
|
+
# Extlib::Logger.set_log(log{String, IO},level{Symbol, String})
|
6
6
|
#
|
7
7
|
# Available logging levels are
|
8
|
-
#
|
8
|
+
# Extlib::Logger::{ Fatal, Error, Warn, Info, Debug }
|
9
9
|
#
|
10
10
|
# Logging via:
|
11
|
-
#
|
12
|
-
#
|
13
|
-
#
|
14
|
-
#
|
15
|
-
#
|
11
|
+
# Extlib.logger.fatal(message<String>,&block)
|
12
|
+
# Extlib.logger.error(message<String>,&block)
|
13
|
+
# Extlib.logger.warn(message<String>,&block)
|
14
|
+
# Extlib.logger.info(message<String>,&block)
|
15
|
+
# Extlib.logger.debug(message<String>,&block)
|
16
16
|
#
|
17
17
|
# Logging with autoflush:
|
18
|
-
#
|
19
|
-
#
|
20
|
-
#
|
21
|
-
#
|
22
|
-
#
|
18
|
+
# Extlib.logger.fatal!(message<String>,&block)
|
19
|
+
# Extlib.logger.error!(message<String>,&block)
|
20
|
+
# Extlib.logger.warn!(message<String>,&block)
|
21
|
+
# Extlib.logger.info!(message<String>,&block)
|
22
|
+
# Extlib.logger.debug!(message<String>,&block)
|
23
23
|
#
|
24
24
|
# Flush the buffer to
|
25
|
-
#
|
25
|
+
# Extlib.logger.flush
|
26
26
|
#
|
27
27
|
# Remove the current log object
|
28
|
-
#
|
28
|
+
# Extlib.logger.close
|
29
29
|
#
|
30
|
-
# ==== Private
|
30
|
+
# ==== Private Extlib Logger API
|
31
31
|
#
|
32
32
|
# To initialize the logger you create a new object, proxies to set_log.
|
33
|
-
#
|
33
|
+
# Extlib::Logger.new(log{String, IO},level{Symbol, String})
|
34
34
|
module Extlib
|
35
35
|
|
36
36
|
class << self
|
@@ -110,8 +110,6 @@ module Extlib
|
|
110
110
|
def set_log(log, log_level = nil, delimiter = " ~ ", auto_flush = false)
|
111
111
|
if log_level && Levels[log_level.to_sym]
|
112
112
|
@level = Levels[log_level.to_sym]
|
113
|
-
elsif Merb.environment == "production"
|
114
|
-
@level = Levels[:warn]
|
115
113
|
else
|
116
114
|
@level = Levels[:debug]
|
117
115
|
end
|
@@ -120,8 +118,6 @@ module Extlib
|
|
120
118
|
@auto_flush = auto_flush
|
121
119
|
|
122
120
|
initialize_log(log)
|
123
|
-
|
124
|
-
Merb.logger = self
|
125
121
|
end
|
126
122
|
|
127
123
|
# Flush the entire buffer to the log object.
|
@@ -157,7 +153,7 @@ module Extlib
|
|
157
153
|
end
|
158
154
|
alias :push :<<
|
159
155
|
|
160
|
-
# Generate the logging methods for
|
156
|
+
# Generate the logging methods for Extlib.logger for each log level.
|
161
157
|
Levels.each_pair do |name, number|
|
162
158
|
class_eval <<-LEVELMETHODS, __FILE__, __LINE__
|
163
159
|
|
data/lib/extlib/module.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
class Module
|
2
2
|
def find_const(const_name)
|
3
3
|
if const_name[0..1] == '::'
|
4
|
-
Object.
|
4
|
+
Object.full_const_get(const_name[2..-1])
|
5
5
|
else
|
6
6
|
nested_const_lookup(const_name)
|
7
7
|
end
|
@@ -15,31 +15,33 @@ class Module
|
|
15
15
|
|
16
16
|
# Doesn't do any caching since constants can change with remove_const
|
17
17
|
def nested_const_lookup(const_name)
|
18
|
-
|
18
|
+
unless equal?(Object)
|
19
|
+
constants = []
|
19
20
|
|
20
|
-
|
21
|
-
|
22
|
-
constants.
|
21
|
+
name.split('::').each do |part|
|
22
|
+
const = constants.first || Object
|
23
|
+
constants << const.const_get(part)
|
23
24
|
end
|
24
|
-
end
|
25
25
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
26
|
+
parts = const_name.split('::')
|
27
|
+
|
28
|
+
# from most to least specific constant, use each as a base and try
|
29
|
+
# to find a constant with the name const_name within them
|
30
|
+
constants.reverse_each do |const|
|
31
|
+
# return the nested constant if available
|
32
|
+
return const if parts.all? do |part|
|
33
|
+
const = if RUBY_VERSION >= '1.9.0'
|
34
|
+
const.const_defined?(part, false) ? const.const_get(part, false) : nil
|
35
|
+
else
|
36
|
+
const.const_defined?(part) ? const.const_get(part) : nil
|
37
|
+
end
|
37
38
|
end
|
38
39
|
end
|
39
40
|
end
|
40
41
|
|
41
|
-
#
|
42
|
-
|
42
|
+
# no relative constant found, fallback to an absolute lookup and
|
43
|
+
# use const_missing if not found
|
44
|
+
Object.full_const_get(const_name)
|
43
45
|
end
|
44
46
|
|
45
47
|
end # class Module
|
data/lib/extlib/object.rb
CHANGED
@@ -97,7 +97,7 @@ class Object
|
|
97
97
|
current_module = self
|
98
98
|
mod.each do |x|
|
99
99
|
unless current_module.const_defined?(x)
|
100
|
-
current_module.class_eval "module #{x}; end"
|
100
|
+
current_module.class_eval "module #{x}; end", __FILE__, __LINE__
|
101
101
|
end
|
102
102
|
current_module = current_module.const_get(x)
|
103
103
|
end
|
@@ -136,6 +136,19 @@ class Object
|
|
136
136
|
self.dup
|
137
137
|
end
|
138
138
|
|
139
|
+
# If receiver is callable, calls it and
|
140
|
+
# returns result. If not, just returns receiver
|
141
|
+
# itself
|
142
|
+
#
|
143
|
+
# @return <Object>
|
144
|
+
def try_call(*args)
|
145
|
+
if self.respond_to?(:call)
|
146
|
+
self.call(*args)
|
147
|
+
else
|
148
|
+
self
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
139
152
|
# @param arrayish<#include?> Container to check, to see if it includes the object.
|
140
153
|
# @param *more<Array>:: additional args, will be flattened into arrayish
|
141
154
|
#
|
data/lib/extlib/pathname.rb
CHANGED
data/lib/extlib/pooling.rb
CHANGED
@@ -26,11 +26,11 @@ module Extlib
|
|
26
26
|
module Pooling
|
27
27
|
|
28
28
|
def self.scavenger?
|
29
|
-
@scavenger && @scavenger.alive?
|
29
|
+
defined?(@scavenger) && !@scavenger.nil? && @scavenger.alive?
|
30
30
|
end
|
31
31
|
|
32
32
|
def self.scavenger
|
33
|
-
|
33
|
+
unless scavenger?
|
34
34
|
@scavenger = Thread.new do
|
35
35
|
running = true
|
36
36
|
while running do
|
@@ -72,7 +72,7 @@ module Extlib
|
|
72
72
|
lock.synchronize do
|
73
73
|
pools << pool
|
74
74
|
end
|
75
|
-
Extlib::Pooling
|
75
|
+
Extlib::Pooling.scavenger
|
76
76
|
end
|
77
77
|
|
78
78
|
def self.lock
|
@@ -118,6 +118,10 @@ module Extlib
|
|
118
118
|
@__pool.release(self) unless @__pool.nil?
|
119
119
|
end
|
120
120
|
|
121
|
+
def detach
|
122
|
+
@__pool.delete(self) unless @__pool.nil?
|
123
|
+
end
|
124
|
+
|
121
125
|
class Pool
|
122
126
|
attr_reader :available
|
123
127
|
attr_reader :used
|
@@ -132,7 +136,7 @@ module Extlib
|
|
132
136
|
|
133
137
|
@available = []
|
134
138
|
@used = {}
|
135
|
-
Extlib::Pooling
|
139
|
+
Extlib::Pooling.append_pool(self)
|
136
140
|
end
|
137
141
|
|
138
142
|
def lock
|
@@ -209,7 +213,7 @@ module Extlib
|
|
209
213
|
def dispose
|
210
214
|
flush!
|
211
215
|
@resource.__pools.delete(@args)
|
212
|
-
!Extlib::Pooling
|
216
|
+
!Extlib::Pooling.pools.delete?(self).nil?
|
213
217
|
end
|
214
218
|
|
215
219
|
def expired?
|
data/lib/extlib/time.rb
CHANGED
@@ -23,6 +23,7 @@ class Time
|
|
23
23
|
# @return [Time] Receiver
|
24
24
|
#
|
25
25
|
# @api public
|
26
|
+
remove_method :to_time if method_defined?(:to_time) || private_method_defined?(:to_time)
|
26
27
|
def to_time
|
27
28
|
self
|
28
29
|
end
|
@@ -35,6 +36,7 @@ class Time
|
|
35
36
|
# @return [DateTime] DateTime object representing the same moment as receiver
|
36
37
|
#
|
37
38
|
# @api public
|
39
|
+
remove_method :to_datetime if method_defined?(:to_datetime) || private_method_defined?(:to_datetime)
|
38
40
|
def to_datetime
|
39
41
|
DateTime.parse self.to_s
|
40
42
|
end
|
data/lib/extlib/version.rb
CHANGED
data/spec/array_spec.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper'))
|
2
|
+
|
3
|
+
describe Array do
|
4
|
+
before :all do
|
5
|
+
@array = [ [ :a, [ 1 ] ], [ :b, [ 2 ] ], [ :c, [ 3 ] ] ].freeze
|
6
|
+
end
|
7
|
+
|
8
|
+
it { @array.should respond_to(:to_hash) }
|
9
|
+
|
10
|
+
describe '#to_hash' do
|
11
|
+
before :all do
|
12
|
+
@return = @array.to_hash
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'should return a Hash' do
|
16
|
+
@return.should be_kind_of(Hash)
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should return expected value' do
|
20
|
+
@return.should == { :a => [ 1 ], :b => [ 2 ], :c => [ 3 ] }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
it { @array.should respond_to(:to_mash) }
|
25
|
+
|
26
|
+
describe '#to_mash' do
|
27
|
+
before :all do
|
28
|
+
@return = @array.to_mash
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'should return a Mash' do
|
32
|
+
@return.should be_kind_of(Mash)
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'should return expected value' do
|
36
|
+
@return.should == { 'a' => [ 1 ], 'b' => [ 2 ], 'c' => [ 3 ] }
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/spec/hook_spec.rb
CHANGED
@@ -2,7 +2,7 @@ require File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper'))
|
|
2
2
|
|
3
3
|
describe Extlib::Hook do
|
4
4
|
|
5
|
-
before
|
5
|
+
before do
|
6
6
|
@module = Module.new do
|
7
7
|
def greet; greetings_from_module; end;
|
8
8
|
end
|
@@ -405,7 +405,9 @@ describe Extlib::Hook do
|
|
405
405
|
def self.method_with_args(one, two, three); end;
|
406
406
|
def self.before_method_with_args(one, two, three); hi_mom!; end;
|
407
407
|
before_class_method(:method_with_args, :before_method_with_args)
|
408
|
+
orig_verbose, $VERBOSE = $VERBOSE, false
|
408
409
|
def self.before_method_with_args; hi_dad!; end;
|
410
|
+
$VERBOSE = orig_verbose
|
409
411
|
end
|
410
412
|
|
411
413
|
@class.should_not_receive(:hi_mom1)
|
@@ -440,7 +442,9 @@ describe Extlib::Hook do
|
|
440
442
|
def self.method_with_args(word, lol); end;
|
441
443
|
def self.before_method_with_args; hi_mom!; end;
|
442
444
|
before_class_method(:method_with_args, :before_method_with_args)
|
445
|
+
orig_verbose, $VERBOSE = $VERBOSE, false
|
443
446
|
def self.before_method_with_args(word, lol); hi_dad!(word, lol); end;
|
447
|
+
$VERBOSE = orig_verbose
|
444
448
|
end
|
445
449
|
|
446
450
|
@class.should_not_receive(:hi_mom!)
|
@@ -541,7 +545,9 @@ describe Extlib::Hook do
|
|
541
545
|
def method_with_args(one, two, three); end;
|
542
546
|
def before_method_with_args(one, two, three); hi_mom!; end;
|
543
547
|
before(:method_with_args, :before_method_with_args)
|
548
|
+
orig_verbose, $VERBOSE = $VERBOSE, false
|
544
549
|
def before_method_with_args; hi_dad!; end;
|
550
|
+
$VERBOSE = orig_verbose
|
545
551
|
end
|
546
552
|
|
547
553
|
inst = @class.new
|
@@ -578,7 +584,9 @@ describe Extlib::Hook do
|
|
578
584
|
def method_with_args(word, lol); end;
|
579
585
|
def before_method_with_args; hi_mom!; end;
|
580
586
|
before(:method_with_args, :before_method_with_args)
|
587
|
+
orig_verbose, $VERBOSE = $VERBOSE, false
|
581
588
|
def before_method_with_args(word, lol); hi_dad!(word, lol); end;
|
589
|
+
$VERBOSE = orig_verbose
|
582
590
|
end
|
583
591
|
|
584
592
|
inst = @class.new
|
data/spec/lazy_array_spec.rb
CHANGED
@@ -0,0 +1,38 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper'))
|
2
|
+
require 'extlib/lazy_module'
|
3
|
+
|
4
|
+
describe LazyModule do
|
5
|
+
describe "instantiated with a block" do
|
6
|
+
it "defers block body evaluation" do
|
7
|
+
lambda do
|
8
|
+
LazyModule.new do
|
9
|
+
raise "Will only be evaluated when mixed in"
|
10
|
+
end
|
11
|
+
end.should_not raise_error
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
describe "included into hosting class" do
|
17
|
+
before :all do
|
18
|
+
KlazzyLazyModule = LazyModule.new do
|
19
|
+
def self.klassy
|
20
|
+
"Klazz"
|
21
|
+
end
|
22
|
+
|
23
|
+
def instancy
|
24
|
+
"Instanzz"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
@klass = Class.new do
|
29
|
+
include KlazzyLazyModule
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
it "class evals block body" do
|
34
|
+
@klass.klassy.should == "Klazz"
|
35
|
+
@klass.new.instancy.should == "Instanzz"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/spec/pooling_spec.rb
CHANGED
@@ -2,8 +2,11 @@ require File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper'))
|
|
2
2
|
require 'timeout'
|
3
3
|
|
4
4
|
module Extlib::Pooling
|
5
|
-
|
6
|
-
|
5
|
+
class << self
|
6
|
+
remove_method :scavenger_interval if method_defined?(:scavenger_interval) || private_method_defined?(:scavenger_interval)
|
7
|
+
def scavenger_interval
|
8
|
+
1
|
9
|
+
end
|
7
10
|
end
|
8
11
|
end
|
9
12
|
|
@@ -11,7 +14,7 @@ describe "Extlib::Pooling" do
|
|
11
14
|
before do
|
12
15
|
|
13
16
|
Object.send(:remove_const, :Person) if defined?(Person)
|
14
|
-
class Person
|
17
|
+
class ::Person
|
15
18
|
include Extlib::Pooling
|
16
19
|
|
17
20
|
attr_accessor :name
|
@@ -26,7 +29,7 @@ describe "Extlib::Pooling" do
|
|
26
29
|
end
|
27
30
|
|
28
31
|
Object.send(:remove_const, :Overwriter) if defined?(Overwriter)
|
29
|
-
class Overwriter
|
32
|
+
class ::Overwriter
|
30
33
|
|
31
34
|
def self.new(*args)
|
32
35
|
instance = allocate
|
@@ -52,13 +55,16 @@ describe "Extlib::Pooling" do
|
|
52
55
|
@overwritten = value
|
53
56
|
end
|
54
57
|
|
55
|
-
|
56
|
-
pool_size
|
57
|
-
|
58
|
-
|
59
|
-
|
58
|
+
class << self
|
59
|
+
remove_method :pool_size if method_defined?(:pool_size) || private_method_defined?(:pool_size)
|
60
|
+
def pool_size
|
61
|
+
pool_size = if RUBY_PLATFORM =~ /java/
|
62
|
+
20
|
63
|
+
else
|
64
|
+
2
|
65
|
+
end
|
66
|
+
pool_size
|
60
67
|
end
|
61
|
-
pool_size
|
62
68
|
end
|
63
69
|
|
64
70
|
def dispose
|
@@ -146,7 +152,6 @@ describe "Extlib::Pooling" do
|
|
146
152
|
end
|
147
153
|
|
148
154
|
it "should wake up the scavenger thread when exiting" do
|
149
|
-
pending 'Fix for JRuby' if RUBY_PLATFORM =~ /java/
|
150
155
|
bob = Person.new('Bob')
|
151
156
|
bob.release
|
152
157
|
Extlib.exiting = true
|
@@ -154,6 +159,13 @@ describe "Extlib::Pooling" do
|
|
154
159
|
Extlib::Pooling.scavenger?.should be_false
|
155
160
|
end
|
156
161
|
|
162
|
+
it "should be able to detach an instance from the pool" do
|
163
|
+
bob = Person.new('Bob')
|
164
|
+
Person.__pools[['Bob']].size.should == 1
|
165
|
+
bob.detach
|
166
|
+
Person.__pools[['Bob']].size.should == 0
|
167
|
+
end
|
168
|
+
|
157
169
|
end
|
158
170
|
|
159
171
|
# describe Extlib::Pooling::ResourcePool do
|
data/spec/spec.opts
ADDED
data/spec/spec_helper.rb
CHANGED
@@ -0,0 +1,73 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper'))
|
2
|
+
|
3
|
+
describe "#try_call" do
|
4
|
+
describe "with an Object" do
|
5
|
+
before :all do
|
6
|
+
@receiver = Object.new
|
7
|
+
end
|
8
|
+
|
9
|
+
it "returns receiver itself" do
|
10
|
+
@receiver.try_call.should == @receiver
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "with a number" do
|
15
|
+
before :all do
|
16
|
+
@receiver = 42
|
17
|
+
end
|
18
|
+
|
19
|
+
it "returns receiver itself" do
|
20
|
+
@receiver.try_call.should == @receiver
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "with a String" do
|
25
|
+
before :all do
|
26
|
+
@receiver = "Ruby, programmer's best friend"
|
27
|
+
end
|
28
|
+
|
29
|
+
it "returns receiver itself" do
|
30
|
+
@receiver.try_call.should == @receiver
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "with a hash" do
|
35
|
+
before :all do
|
36
|
+
@receiver = { :functional_programming => "FTW" }
|
37
|
+
end
|
38
|
+
|
39
|
+
it "returns receiver itself" do
|
40
|
+
@receiver.try_call.should == @receiver
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe "with a Proc" do
|
45
|
+
before :all do
|
46
|
+
@receiver = Proc.new { 5 * 7 }
|
47
|
+
end
|
48
|
+
|
49
|
+
it "returns result of calling of a proc" do
|
50
|
+
@receiver.try_call.should == 35
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "with a Proc that takes 2 arguments" do
|
55
|
+
before :all do
|
56
|
+
@receiver = Proc.new { |one, other| one + other }
|
57
|
+
end
|
58
|
+
|
59
|
+
it "passes arguments to #call, returns result of calling of a proc" do
|
60
|
+
@receiver.try_call(10, 20).should == 30
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe "with a Proc that takes 3 arguments" do
|
65
|
+
before :all do
|
66
|
+
@receiver = Proc.new { |a, b, c| (a + b) * c }
|
67
|
+
end
|
68
|
+
|
69
|
+
it "passes arguments to #call, returns result of calling of a proc" do
|
70
|
+
@receiver.try_call(10, 20, 3).should == 90
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
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.11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sam Smoot
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-03-29 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -29,9 +29,11 @@ files:
|
|
29
29
|
- Rakefile
|
30
30
|
- History.txt
|
31
31
|
- lib/extlib
|
32
|
+
- lib/extlib/array.rb
|
32
33
|
- lib/extlib/assertions.rb
|
33
34
|
- lib/extlib/blank.rb
|
34
35
|
- lib/extlib/boolean.rb
|
36
|
+
- lib/extlib/byte_array.rb
|
35
37
|
- lib/extlib/class.rb
|
36
38
|
- lib/extlib/datetime.rb
|
37
39
|
- lib/extlib/dictionary.rb
|
@@ -39,6 +41,7 @@ files:
|
|
39
41
|
- lib/extlib/hook.rb
|
40
42
|
- lib/extlib/inflection.rb
|
41
43
|
- lib/extlib/lazy_array.rb
|
44
|
+
- lib/extlib/lazy_module.rb
|
42
45
|
- lib/extlib/logger.rb
|
43
46
|
- lib/extlib/mash.rb
|
44
47
|
- lib/extlib/module.rb
|
@@ -59,7 +62,9 @@ files:
|
|
59
62
|
- lib/extlib/version.rb
|
60
63
|
- lib/extlib/virtual_file.rb
|
61
64
|
- lib/extlib.rb
|
65
|
+
- spec/array_spec.rb
|
62
66
|
- spec/blank_spec.rb
|
67
|
+
- spec/byte_array_spec.rb
|
63
68
|
- spec/class_spec.rb
|
64
69
|
- spec/datetime_spec.rb
|
65
70
|
- spec/hash_spec.rb
|
@@ -69,17 +74,20 @@ files:
|
|
69
74
|
- spec/inflection/singular_spec.rb
|
70
75
|
- spec/inflection_extras_spec.rb
|
71
76
|
- spec/lazy_array_spec.rb
|
77
|
+
- spec/lazy_module_spec.rb
|
72
78
|
- spec/mash_spec.rb
|
73
79
|
- spec/module_spec.rb
|
74
80
|
- spec/object_space_spec.rb
|
75
81
|
- spec/object_spec.rb
|
76
82
|
- spec/pooling_spec.rb
|
77
83
|
- spec/simple_set_spec.rb
|
84
|
+
- spec/spec.opts
|
78
85
|
- spec/spec_helper.rb
|
79
86
|
- spec/string_spec.rb
|
80
87
|
- spec/struct_spec.rb
|
81
88
|
- spec/symbol_spec.rb
|
82
89
|
- spec/time_spec.rb
|
90
|
+
- spec/try_call_spec.rb
|
83
91
|
- spec/try_dup_spec.rb
|
84
92
|
- spec/virtual_file_spec.rb
|
85
93
|
has_rdoc: false
|