extlib 0.9.13 → 0.9.14
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/.autotest +21 -0
- data/.document +5 -0
- data/.gitignore +22 -0
- data/LICENSE +1 -1
- data/README.rdoc +17 -0
- data/Rakefile +18 -170
- data/VERSION +1 -0
- data/extlib.gemspec +146 -0
- data/lib/extlib/class.rb +8 -8
- data/lib/extlib/hash.rb +7 -7
- data/lib/extlib/inflection.rb +11 -5
- data/lib/extlib/lazy_array.rb +26 -32
- data/lib/extlib/mash.rb +11 -11
- data/lib/extlib/object.rb +9 -9
- data/lib/extlib/object_space.rb +1 -1
- data/lib/extlib/rubygems.rb +1 -1
- data/lib/extlib/string.rb +4 -3
- data/spec/inflection_extras_spec.rb +18 -1
- data/spec/lazy_array_spec.rb +25 -0
- data/spec/rcov.opts +6 -0
- data/spec/spec.opts +1 -0
- data/spec/string_spec.rb +1 -0
- data/tasks/ci.rake +1 -0
- data/tasks/metrics.rake +36 -0
- data/tasks/spec.rake +25 -0
- data/tasks/yard.rake +9 -0
- data/tasks/yardstick.rake +19 -0
- metadata +81 -20
- data/History.txt +0 -77
- data/README +0 -0
- data/lib/extlib/tasks/release.rb +0 -15
- data/lib/extlib/version.rb +0 -3
data/lib/extlib/hash.rb
CHANGED
@@ -115,7 +115,7 @@ class Hash
|
|
115
115
|
# @param [Object] key The key for the param.
|
116
116
|
# @param [Object] value The value for the param.
|
117
117
|
#
|
118
|
-
# @return
|
118
|
+
# @return [String] This key value pair as a param
|
119
119
|
#
|
120
120
|
# @api public
|
121
121
|
def normalize_param(key, value)
|
@@ -176,7 +176,7 @@ class Hash
|
|
176
176
|
hash
|
177
177
|
end
|
178
178
|
|
179
|
-
# @return
|
179
|
+
# @return [String] The hash as attributes for an XML tag.
|
180
180
|
#
|
181
181
|
# @example
|
182
182
|
# { :one => 1, "two"=>"TWO" }.to_xml_attributes
|
@@ -209,7 +209,7 @@ class Hash
|
|
209
209
|
# Converts all keys into string values. This is used during reloading to
|
210
210
|
# prevent problems when classes are no longer declared.
|
211
211
|
#
|
212
|
-
# @return
|
212
|
+
# @return [Array] An array of they hash's keys
|
213
213
|
#
|
214
214
|
# @example
|
215
215
|
# hash = { One => 1, Two => 2 }.proctect_keys!
|
@@ -234,7 +234,7 @@ class Hash
|
|
234
234
|
# Destructively and non-recursively convert each key to an uppercase string,
|
235
235
|
# deleting nil values along the way.
|
236
236
|
#
|
237
|
-
# @return
|
237
|
+
# @return [Hash] The newly environmentized hash.
|
238
238
|
#
|
239
239
|
# @example
|
240
240
|
# { :name => "Bob", :contact => { :email => "bob@bob.com" } }.environmentize_keys!
|
@@ -361,7 +361,7 @@ class REXMLUtilityNode
|
|
361
361
|
# "date"::
|
362
362
|
# Parses +value+ using Date.parse
|
363
363
|
#
|
364
|
-
# @return
|
364
|
+
# @return [Integer, Boolean, Time, Date, Object]
|
365
365
|
# The result of typecasting +value+.
|
366
366
|
#
|
367
367
|
# @note
|
@@ -377,7 +377,7 @@ class REXMLUtilityNode
|
|
377
377
|
#
|
378
378
|
# @param value<#gsub> An XML fragment.
|
379
379
|
#
|
380
|
-
# @return
|
380
|
+
# @return [#gsub] The XML fragment after converting entities.
|
381
381
|
def translate_xml_entities(value)
|
382
382
|
value.gsub(/</, "<").
|
383
383
|
gsub(/>/, ">").
|
@@ -401,7 +401,7 @@ class REXMLUtilityNode
|
|
401
401
|
|
402
402
|
# Converts the node into a readable HTML node.
|
403
403
|
#
|
404
|
-
# @return
|
404
|
+
# @return [String] The HTML node in text form.
|
405
405
|
def to_html
|
406
406
|
attributes.merge!(:type => @type ) if @type
|
407
407
|
"<#{name}#{attributes.to_xml_attributes}>#{@nil_element ? '' : inner_html}</#{name}>"
|
data/lib/extlib/inflection.rb
CHANGED
@@ -10,10 +10,13 @@ module Extlib
|
|
10
10
|
#
|
11
11
|
# @example
|
12
12
|
# "egg_and_hams".classify #=> "EggAndHam"
|
13
|
+
# "enlarged_testes".classify #=> "EnlargedTestis"
|
13
14
|
# "post".classify #=> "Post"
|
14
15
|
#
|
15
16
|
def classify(name)
|
16
|
-
|
17
|
+
words = name.to_s.sub(/.*\./, '').split('_')
|
18
|
+
words[-1] = singularize(words[-1])
|
19
|
+
words.collect { |word| word.capitalize }.join
|
17
20
|
end
|
18
21
|
|
19
22
|
# By default, camelize converts strings to UpperCamelCase.
|
@@ -48,7 +51,7 @@ module Extlib
|
|
48
51
|
# "employee_salary" #=> "Employee salary"
|
49
52
|
# "author_id" #=> "Author"
|
50
53
|
def humanize(lower_case_and_underscored_word)
|
51
|
-
lower_case_and_underscored_word.to_s.gsub(/_id$/,
|
54
|
+
lower_case_and_underscored_word.to_s.gsub(/_id$/, '').tr('_', ' ').capitalize
|
52
55
|
end
|
53
56
|
|
54
57
|
# Removes the module part from the expression in the string
|
@@ -65,10 +68,13 @@ module Extlib
|
|
65
68
|
#
|
66
69
|
# @example
|
67
70
|
# "RawScaledScorer".tableize #=> "raw_scaled_scorers"
|
71
|
+
# "EnlargedTestis".tableize #=> "enlarged_testes"
|
68
72
|
# "egg_and_ham".tableize #=> "egg_and_hams"
|
69
73
|
# "fancyCategory".tableize #=> "fancy_categories"
|
70
74
|
def tableize(class_name)
|
71
|
-
|
75
|
+
words = class_name.to_const_path.tr('/', '_').split('_')
|
76
|
+
words[-1] = pluralize(words[-1])
|
77
|
+
words.join('_')
|
72
78
|
end
|
73
79
|
|
74
80
|
# Creates a foreign key name from a class name.
|
@@ -253,7 +259,7 @@ module Extlib
|
|
253
259
|
|
254
260
|
attr_reader :singular_of, :plural_of
|
255
261
|
|
256
|
-
# Convert an English word from
|
262
|
+
# Convert an English word from plural to singular.
|
257
263
|
#
|
258
264
|
# "boys".singular #=> boy
|
259
265
|
# "tomatoes".singular #=> tomato
|
@@ -281,7 +287,7 @@ module Extlib
|
|
281
287
|
#
|
282
288
|
alias_method(:singularize, :singular)
|
283
289
|
|
284
|
-
# Convert an English word from singular to
|
290
|
+
# Convert an English word from singular to plural.
|
285
291
|
#
|
286
292
|
# "boy".plural #=> boys
|
287
293
|
# "tomato".plural #=> tomatoes
|
data/lib/extlib/lazy_array.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
class LazyArray # borrowed partially from StrokeDB
|
2
|
-
|
2
|
+
include Enumerable
|
3
3
|
|
4
4
|
attr_reader :head, :tail
|
5
5
|
|
@@ -82,7 +82,11 @@ class LazyArray # borrowed partially from StrokeDB
|
|
82
82
|
end
|
83
83
|
|
84
84
|
def empty?
|
85
|
-
|
85
|
+
(@tail.nil? || @tail.empty?) &&
|
86
|
+
(@head.nil? || @head.empty?) && begin
|
87
|
+
lazy_load
|
88
|
+
@array.empty?
|
89
|
+
end
|
86
90
|
end
|
87
91
|
|
88
92
|
def any?(&block)
|
@@ -214,21 +218,21 @@ class LazyArray # borrowed partially from StrokeDB
|
|
214
218
|
self
|
215
219
|
end
|
216
220
|
|
217
|
-
def pop
|
218
|
-
if lazy_possible?(@tail)
|
219
|
-
@tail.pop
|
221
|
+
def pop(*args)
|
222
|
+
if lazy_possible?(@tail, *args)
|
223
|
+
@tail.pop(*args)
|
220
224
|
else
|
221
225
|
lazy_load
|
222
|
-
@array.pop
|
226
|
+
@array.pop(*args)
|
223
227
|
end
|
224
228
|
end
|
225
229
|
|
226
|
-
def shift
|
227
|
-
if lazy_possible?(@head)
|
228
|
-
@head.shift
|
230
|
+
def shift(*args)
|
231
|
+
if lazy_possible?(@head, *args)
|
232
|
+
@head.shift(*args)
|
229
233
|
else
|
230
234
|
lazy_load
|
231
|
-
@array.shift
|
235
|
+
@array.shift(*args)
|
232
236
|
end
|
233
237
|
end
|
234
238
|
|
@@ -401,6 +405,16 @@ class LazyArray # borrowed partially from StrokeDB
|
|
401
405
|
raise ArgumentError, "arguments may be 1 or 2 Integers, or 1 Range object, was: #{args.inspect}", caller(1)
|
402
406
|
end
|
403
407
|
|
408
|
+
def each
|
409
|
+
lazy_load
|
410
|
+
if block_given?
|
411
|
+
@array.each { |entry| yield entry }
|
412
|
+
self
|
413
|
+
else
|
414
|
+
@array.each
|
415
|
+
end
|
416
|
+
end
|
417
|
+
|
404
418
|
# delegate any not-explicitly-handled methods to @array, if possible.
|
405
419
|
# this is handy for handling methods mixed-into Array like group_by
|
406
420
|
def method_missing(method, *args, &block)
|
@@ -419,14 +433,14 @@ class LazyArray # borrowed partially from StrokeDB
|
|
419
433
|
# 0 and incrementally compare each entry. if other is a LazyArray
|
420
434
|
# this has a lesser likelyhood of triggering a lazy load
|
421
435
|
0.upto(@head.size - 1) do |i|
|
422
|
-
return false unless @head[i].
|
436
|
+
return false unless @head[i].__send__(operator, other[i])
|
423
437
|
end
|
424
438
|
|
425
439
|
# compare the tail against the end of other. start at index
|
426
440
|
# -1 and decrementally compare each entry. if other is a LazyArray
|
427
441
|
# this has a lesser likelyhood of triggering a lazy load
|
428
442
|
-1.downto(@tail.size * -1) do |i|
|
429
|
-
return false unless @tail[i].
|
443
|
+
return false unless @tail[i].__send__(operator, other[i])
|
430
444
|
end
|
431
445
|
|
432
446
|
lazy_load
|
@@ -434,24 +448,4 @@ class LazyArray # borrowed partially from StrokeDB
|
|
434
448
|
|
435
449
|
@array.send(operator, other.to_ary)
|
436
450
|
end
|
437
|
-
|
438
|
-
# add proxies for all remaining Array and Enumerable methods
|
439
|
-
(Array.public_instance_methods(false) | Enumerable.public_instance_methods(false)).each do |method|
|
440
|
-
next if public_method_defined?(method)
|
441
|
-
|
442
|
-
target = if method.to_s[-1, 1] == '='
|
443
|
-
"send(:#{method}, *args, &block)"
|
444
|
-
else
|
445
|
-
"#{method}(*args, &block)"
|
446
|
-
end
|
447
|
-
|
448
|
-
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
449
|
-
public
|
450
|
-
def #{method}(*args, &block) # def []=(*args, &block)
|
451
|
-
lazy_load # lazy_load
|
452
|
-
results = @array.#{target} # results = @array.send(:[]=, *args, &block)
|
453
|
-
results.equal?(@array) ? self : results # results.equal?(@array) ? self : results
|
454
|
-
end # end
|
455
|
-
RUBY
|
456
|
-
end
|
457
451
|
end
|
data/lib/extlib/mash.rb
CHANGED
@@ -47,7 +47,7 @@ class Mash < Hash
|
|
47
47
|
# A hash to update values in the mash with. The keys and the values will be
|
48
48
|
# converted to Mash format.
|
49
49
|
#
|
50
|
-
# @return
|
50
|
+
# @return [Mash] The updated mash.
|
51
51
|
def update(other_hash)
|
52
52
|
other_hash.each_pair { |key, value| regular_writer(convert_key(key), convert_value(value)) }
|
53
53
|
self
|
@@ -57,7 +57,7 @@ class Mash < Hash
|
|
57
57
|
|
58
58
|
# @param key<Object> The key to check for. This will be run through convert_key.
|
59
59
|
#
|
60
|
-
# @return
|
60
|
+
# @return [Boolean] True if the key exists in the mash.
|
61
61
|
def key?(key)
|
62
62
|
super(convert_key(key))
|
63
63
|
end
|
@@ -70,7 +70,7 @@ class Mash < Hash
|
|
70
70
|
# @param key<Object> The key to fetch. This will be run through convert_key.
|
71
71
|
# @param *extras<Array> Default value.
|
72
72
|
#
|
73
|
-
# @return
|
73
|
+
# @return [Object] The value at key or the default value.
|
74
74
|
def fetch(key, *extras)
|
75
75
|
super(convert_key(key), *extras)
|
76
76
|
end
|
@@ -78,14 +78,14 @@ class Mash < Hash
|
|
78
78
|
# @param *indices<Array>
|
79
79
|
# The keys to retrieve values for. These will be run through +convert_key+.
|
80
80
|
#
|
81
|
-
# @return
|
81
|
+
# @return [Array] The values at each of the provided keys
|
82
82
|
def values_at(*indices)
|
83
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
|
-
# @return
|
88
|
+
# @return [Mash] A new mash with the hash values merged in.
|
89
89
|
def merge(hash)
|
90
90
|
self.dup.update(hash)
|
91
91
|
end
|
@@ -98,7 +98,7 @@ class Mash < Hash
|
|
98
98
|
|
99
99
|
# @param *rejected<Array[(String, Symbol)] The mash keys to exclude.
|
100
100
|
#
|
101
|
-
# @return
|
101
|
+
# @return [Mash] A new mash without the selected keys.
|
102
102
|
#
|
103
103
|
# @example
|
104
104
|
# { :one => 1, :two => 2, :three => 3 }.except(:one)
|
@@ -109,17 +109,17 @@ class Mash < Hash
|
|
109
109
|
|
110
110
|
# Used to provide the same interface as Hash.
|
111
111
|
#
|
112
|
-
# @return
|
112
|
+
# @return [Mash] This mash unchanged.
|
113
113
|
def stringify_keys!; self end
|
114
114
|
|
115
|
-
# @return
|
115
|
+
# @return [Hash] The mash as a Hash with symbolized keys.
|
116
116
|
def symbolize_keys
|
117
117
|
h = Hash.new(default)
|
118
118
|
each { |key, val| h[key.to_sym] = val }
|
119
119
|
h
|
120
120
|
end
|
121
121
|
|
122
|
-
# @return
|
122
|
+
# @return [Hash] The mash as a Hash with string keys.
|
123
123
|
def to_hash
|
124
124
|
Hash.new(default).merge(self)
|
125
125
|
end
|
@@ -127,7 +127,7 @@ class Mash < Hash
|
|
127
127
|
protected
|
128
128
|
# @param key<Object> The key to convert.
|
129
129
|
#
|
130
|
-
# @param
|
130
|
+
# @param [Object]
|
131
131
|
# The converted key. If the key was a symbol, it will be converted to a
|
132
132
|
# string.
|
133
133
|
#
|
@@ -138,7 +138,7 @@ class Mash < Hash
|
|
138
138
|
|
139
139
|
# @param value<Object> The value to convert.
|
140
140
|
#
|
141
|
-
# @return
|
141
|
+
# @return [Object]
|
142
142
|
# The converted value. A Hash or an Array of hashes, will be converted to
|
143
143
|
# their Mash equivalents.
|
144
144
|
#
|
data/lib/extlib/object.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
class Object
|
2
2
|
# Extracts the singleton class, so that metaprogramming can be done on it.
|
3
3
|
#
|
4
|
-
# @return
|
4
|
+
# @return [Class] The meta class.
|
5
5
|
#
|
6
6
|
# @example [Setup]
|
7
7
|
# class MyString < String; end
|
@@ -60,7 +60,7 @@ class Object
|
|
60
60
|
|
61
61
|
# @param name<String> The name of the constant to get, e.g. "Merb::Router".
|
62
62
|
#
|
63
|
-
# @return
|
63
|
+
# @return [Object] The constant corresponding to the name.
|
64
64
|
def full_const_get(name)
|
65
65
|
list = name.split("::")
|
66
66
|
list.shift if list.first.blank?
|
@@ -76,7 +76,7 @@ class Object
|
|
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
|
-
# @return
|
79
|
+
# @return [Object] The constant corresponding to the name.
|
80
80
|
def full_const_set(name, value)
|
81
81
|
list = name.split("::")
|
82
82
|
toplevel = list.first.blank?
|
@@ -91,7 +91,7 @@ class Object
|
|
91
91
|
#
|
92
92
|
# @param name<String> The name of the full module name to make
|
93
93
|
#
|
94
|
-
# @return
|
94
|
+
# @return [nil]
|
95
95
|
def make_module(str)
|
96
96
|
mod = str.split("::")
|
97
97
|
current_module = self
|
@@ -114,7 +114,7 @@ class Object
|
|
114
114
|
# Check whether the object quacks_like? at least one of the options in the
|
115
115
|
# array.
|
116
116
|
#
|
117
|
-
# @return
|
117
|
+
# @return [Boolean]
|
118
118
|
# True if the object quacks like duck.
|
119
119
|
def quacks_like?(duck)
|
120
120
|
case duck
|
@@ -131,7 +131,7 @@ class Object
|
|
131
131
|
|
132
132
|
# Override this in a child if it cannot be dup'ed
|
133
133
|
#
|
134
|
-
# @return
|
134
|
+
# @return [Object]
|
135
135
|
def try_dup
|
136
136
|
self.dup
|
137
137
|
end
|
@@ -140,7 +140,7 @@ class Object
|
|
140
140
|
# returns result. If not, just returns receiver
|
141
141
|
# itself
|
142
142
|
#
|
143
|
-
# @return
|
143
|
+
# @return [Object]
|
144
144
|
def try_call(*args)
|
145
145
|
if self.respond_to?(:call)
|
146
146
|
self.call(*args)
|
@@ -152,7 +152,7 @@ class Object
|
|
152
152
|
# @param arrayish<#include?> Container to check, to see if it includes the object.
|
153
153
|
# @param *more<Array>:: additional args, will be flattened into arrayish
|
154
154
|
#
|
155
|
-
# @return
|
155
|
+
# @return [Boolean]
|
156
156
|
# True if the object is included in arrayish (+ more)
|
157
157
|
#
|
158
158
|
# @example 1.in?([1,2,3]) #=> true
|
@@ -165,7 +165,7 @@ class Object
|
|
165
165
|
# Add instance_variable_defined? for backward compatibility
|
166
166
|
# @param variable<Symbol, String>
|
167
167
|
#
|
168
|
-
# @return
|
168
|
+
# @return [Boolean]
|
169
169
|
# True if the object has the given instance variable defined
|
170
170
|
unless respond_to?(:instance_variable_defined?)
|
171
171
|
def instance_variable_defined?(variable)
|
data/lib/extlib/object_space.rb
CHANGED
data/lib/extlib/rubygems.rb
CHANGED
@@ -30,7 +30,7 @@ module Gem
|
|
30
30
|
# from any other location. If there are two gems of different versions in
|
31
31
|
# the gems directory, the later one will load as usual.
|
32
32
|
#
|
33
|
-
# @return <Array
|
33
|
+
# @return [Array<Array>] The object used for sorting gem specs.
|
34
34
|
def sort_obj
|
35
35
|
[@name, installation_path == File.join(defined?(Merb) && Merb.respond_to?(:root) ? Merb.root : Dir.pwd,"gems") ? 1 : -1, @version.to_ints, @new_platform == Gem::Platform::RUBY ? -1 : 1]
|
36
36
|
end
|
data/lib/extlib/string.rb
CHANGED
@@ -36,9 +36,10 @@ class String
|
|
36
36
|
#
|
37
37
|
# @api public
|
38
38
|
def snake_case
|
39
|
-
return
|
40
|
-
|
41
|
-
|
39
|
+
return downcase if match(/\A[A-Z]+\z/)
|
40
|
+
gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2').
|
41
|
+
gsub(/([a-z])([A-Z])/, '\1_\2').
|
42
|
+
downcase
|
42
43
|
end
|
43
44
|
|
44
45
|
##
|
@@ -2,10 +2,14 @@ require File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper'))
|
|
2
2
|
|
3
3
|
describe Extlib::Inflection do
|
4
4
|
describe "#classify" do
|
5
|
-
it 'classifies data_mapper as
|
5
|
+
it 'classifies data_mapper as DataMapper' do
|
6
6
|
Extlib::Inflection.classify('data_mapper').should == 'DataMapper'
|
7
7
|
end
|
8
8
|
|
9
|
+
it "classifies enlarged_testes as EnlargedTestis" do
|
10
|
+
Extlib::Inflection.classify('enlarged_testes').should == 'EnlargedTestis'
|
11
|
+
end
|
12
|
+
|
9
13
|
it "singularizes string first: classifies data_mappers as egg_and_hams as EggAndHam" do
|
10
14
|
Extlib::Inflection.classify('egg_and_hams').should == 'EggAndHam'
|
11
15
|
end
|
@@ -72,13 +76,26 @@ describe Extlib::Inflection do
|
|
72
76
|
Extlib::Inflection.tableize('fancy_category').should == 'fancy_categories'
|
73
77
|
end
|
74
78
|
|
79
|
+
it 'underscores CamelCase strings before pluralization: enlarged_testis => enlarged_testes' do
|
80
|
+
Extlib::Inflection.tableize('enlarged_testis').should == 'enlarged_testes'
|
81
|
+
end
|
82
|
+
|
75
83
|
it 'underscores CamelCase strings before pluralization: FancyCategory => fancy_categories' do
|
76
84
|
Extlib::Inflection.tableize('FancyCategory').should == 'fancy_categories'
|
77
85
|
end
|
78
86
|
|
87
|
+
it 'underscores CamelCase strings before pluralization: EnlargedTestis => enlarged_testes' do
|
88
|
+
Extlib::Inflection.tableize('EnlargedTestis').should == 'enlarged_testes'
|
89
|
+
end
|
90
|
+
|
79
91
|
it 'replaces :: with underscores: Fancy::Category => fancy_categories' do
|
80
92
|
Extlib::Inflection.tableize('Fancy::Category').should == 'fancy_categories'
|
81
93
|
end
|
94
|
+
|
95
|
+
it 'underscores CamelCase strings before pluralization: Enlarged::Testis => enlarged_testes' do
|
96
|
+
Extlib::Inflection.tableize('Enlarged::Testis').should == 'enlarged_testes'
|
97
|
+
end
|
98
|
+
|
82
99
|
end
|
83
100
|
|
84
101
|
describe "#foreign_key" do
|