ruby_core_extensions 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +4 -0
- data/.rspec +2 -0
- data/.travis.yml +14 -0
- data/Gemfile +2 -0
- data/LICENSE +21 -0
- data/README.md +37 -0
- data/Rakefile +12 -0
- data/gemfiles/rails3.gemfile +11 -0
- data/gemfiles/rails4.gemfile +11 -0
- data/lib/ruby_core_extensions.rb +20 -0
- data/lib/ruby_core_extensions/array.rb +50 -0
- data/lib/ruby_core_extensions/class.rb +8 -0
- data/lib/ruby_core_extensions/compact.rb +2 -0
- data/lib/ruby_core_extensions/compact/array.rb +20 -0
- data/lib/ruby_core_extensions/compact/hash.rb +34 -0
- data/lib/ruby_core_extensions/enumerable.rb +39 -0
- data/lib/ruby_core_extensions/file.rb +12 -0
- data/lib/ruby_core_extensions/hash.rb +34 -0
- data/lib/ruby_core_extensions/kernel.rb +11 -0
- data/lib/ruby_core_extensions/numeric.rb +7 -0
- data/lib/ruby_core_extensions/object.rb +72 -0
- data/lib/ruby_core_extensions/recursive.rb +8 -0
- data/lib/ruby_core_extensions/recursive/array.rb +45 -0
- data/lib/ruby_core_extensions/recursive/big_decimal.rb +5 -0
- data/lib/ruby_core_extensions/recursive/date.rb +8 -0
- data/lib/ruby_core_extensions/recursive/date_time.rb +8 -0
- data/lib/ruby_core_extensions/recursive/fixnum.rb +7 -0
- data/lib/ruby_core_extensions/recursive/hash.rb +86 -0
- data/lib/ruby_core_extensions/recursive/object.rb +17 -0
- data/lib/ruby_core_extensions/recursive/time.rb +8 -0
- data/lib/ruby_core_extensions/string.rb +78 -0
- data/lib/ruby_core_extensions/version.rb +3 -0
- data/ruby_core_extensions.gemspec +32 -0
- data/spec/array_spec.rb +67 -0
- data/spec/class_spec.rb +12 -0
- data/spec/compact_spec.rb +49 -0
- data/spec/enumerable_spec.rb +24 -0
- data/spec/filename_spec.rb +17 -0
- data/spec/hash_spec.rb +107 -0
- data/spec/numeric_spec.rb +12 -0
- data/spec/object_spec.rb +58 -0
- data/spec/spec_helper.rb +17 -0
- data/spec/string_spec.rb +62 -0
- data/spec/support/coverage.rb +29 -0
- metadata +225 -0
@@ -0,0 +1,8 @@
|
|
1
|
+
require 'ruby_core_extensions/recursive/array'
|
2
|
+
require 'ruby_core_extensions/recursive/big_decimal'
|
3
|
+
require 'ruby_core_extensions/recursive/date'
|
4
|
+
require 'ruby_core_extensions/recursive/date_time'
|
5
|
+
require 'ruby_core_extensions/recursive/fixnum'
|
6
|
+
require 'ruby_core_extensions/recursive/hash'
|
7
|
+
require 'ruby_core_extensions/recursive/object'
|
8
|
+
require 'ruby_core_extensions/recursive/time'
|
@@ -0,0 +1,45 @@
|
|
1
|
+
class Array
|
2
|
+
|
3
|
+
def convert
|
4
|
+
self
|
5
|
+
end
|
6
|
+
|
7
|
+
def convert_keys_recursively(&converter)
|
8
|
+
map { |v| v.convert_keys_recursively(&converter) }
|
9
|
+
end
|
10
|
+
|
11
|
+
def convert_values_recursively(&converter)
|
12
|
+
map { |v| v.convert_values_recursively(&converter) }
|
13
|
+
end
|
14
|
+
|
15
|
+
def symbolize_keys_recursively
|
16
|
+
map(&:symbolize_keys_recursively)
|
17
|
+
end
|
18
|
+
|
19
|
+
def stringify_values_recursively
|
20
|
+
map(&:stringify_values_recursively)
|
21
|
+
end
|
22
|
+
|
23
|
+
def make_indifferent_access_recursively
|
24
|
+
map(&:make_indifferent_access_recursively)
|
25
|
+
end
|
26
|
+
|
27
|
+
def recursive_blank?
|
28
|
+
each do |v|
|
29
|
+
if v.respond_to?(:recursive_blank?)
|
30
|
+
return false unless v.recursive_blank?
|
31
|
+
else
|
32
|
+
return false unless v.blank?
|
33
|
+
end
|
34
|
+
end
|
35
|
+
true
|
36
|
+
end
|
37
|
+
|
38
|
+
def recursively(&block)
|
39
|
+
each do |element|
|
40
|
+
block.call(element)
|
41
|
+
element.recursively(&block) if element.respond_to?(:recursively)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
class Hash
|
2
|
+
|
3
|
+
def recursive_blank?
|
4
|
+
each do |k, v|
|
5
|
+
if v.respond_to?(:recursive_blank?)
|
6
|
+
return false unless v.recursive_blank?
|
7
|
+
else
|
8
|
+
return false unless v.blank?
|
9
|
+
end
|
10
|
+
end
|
11
|
+
true
|
12
|
+
end
|
13
|
+
|
14
|
+
def convert
|
15
|
+
self
|
16
|
+
end
|
17
|
+
|
18
|
+
def convert_keys(&converter)
|
19
|
+
inject({}) do |hash, (key, value)|
|
20
|
+
hash[converter.call(key)] = value
|
21
|
+
hash
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def convert_values(*keys, &converter)
|
26
|
+
inject(clone) do |hash, (key, value)|
|
27
|
+
hash[key] = value.convert(&converter) if keys.blank? || keys.include?(key)
|
28
|
+
hash
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def convert_keys_recursively(&converter)
|
33
|
+
Hash[map do |key, value|
|
34
|
+
k = converter.call(key)
|
35
|
+
v = value.convert_keys_recursively(&converter)
|
36
|
+
[k,v]
|
37
|
+
end]
|
38
|
+
end
|
39
|
+
|
40
|
+
def convert_values_recursively(&converter)
|
41
|
+
inject({}) do |hash, (key, value)|
|
42
|
+
hash[key] = value.convert_values_recursively(&converter)
|
43
|
+
hash
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def symbolize_keys_recursively
|
48
|
+
Hash[map do |key, value|
|
49
|
+
k = key.is_a?(String) ? key.to_sym : key
|
50
|
+
v = value.symbolize_keys_recursively
|
51
|
+
[k,v]
|
52
|
+
end]
|
53
|
+
end
|
54
|
+
|
55
|
+
def stringify_values_recursively
|
56
|
+
inject({}) do |options, (key, value)|
|
57
|
+
options[key] = value.stringify_values_recursively
|
58
|
+
options
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def make_indifferent_access_recursively
|
63
|
+
HashWithIndifferentAccess.new(inject({}) do |options, (key, value)|
|
64
|
+
options[key] = value.make_indifferent_access_recursively
|
65
|
+
options
|
66
|
+
end)
|
67
|
+
end
|
68
|
+
|
69
|
+
def deep_dup
|
70
|
+
duplicate = self.dup
|
71
|
+
duplicate.each_pair do |k,v|
|
72
|
+
tv = duplicate[k]
|
73
|
+
duplicate[k] = tv.is_a?(Hash) && v.is_a?(Hash) ? tv.deep_dup : v
|
74
|
+
end
|
75
|
+
duplicate
|
76
|
+
end
|
77
|
+
|
78
|
+
def recursively(&block)
|
79
|
+
each do |key,value|
|
80
|
+
block.call(key,value)
|
81
|
+
value.recursively(&block) if value.respond_to?(:recursively)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class Object
|
2
|
+
def convert(&converter)
|
3
|
+
converter.call(self)
|
4
|
+
end
|
5
|
+
|
6
|
+
def return_self
|
7
|
+
self
|
8
|
+
end
|
9
|
+
|
10
|
+
alias_method :convert_values_recursively, :convert
|
11
|
+
alias_method :convert_recursively, :convert
|
12
|
+
|
13
|
+
alias_method :convert_keys_recursively, :return_self
|
14
|
+
alias_method :symbolize_keys_recursively, :return_self
|
15
|
+
alias_method :stringify_values_recursively, :return_self
|
16
|
+
alias_method :make_indifferent_access_recursively, :return_self
|
17
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
class String
|
2
|
+
def proper_underscore
|
3
|
+
self.titleize.gsub(" ","").underscore
|
4
|
+
end
|
5
|
+
|
6
|
+
# Generate a phonetic code - which is the same for similar sounding names
|
7
|
+
def phonetic_code
|
8
|
+
# Currently using 'metaphone' which is more accurate than soundex
|
9
|
+
Text::Metaphone.metaphone(self)
|
10
|
+
end
|
11
|
+
|
12
|
+
# Solr requires numbers and letters to be separated
|
13
|
+
def separate_numbers_and_letters
|
14
|
+
gsub(/[a-z][0-9]|[0-9][a-z]/i){ |s| s[0].chr + ' ' + s[1].chr }
|
15
|
+
end
|
16
|
+
|
17
|
+
# convert newlines to breaks
|
18
|
+
def nl2br
|
19
|
+
gsub(/\n/, '<br />')
|
20
|
+
end
|
21
|
+
|
22
|
+
# Squash will reduce words from the end of the string to 3 characters until it
|
23
|
+
# fits within the limit, shrinking all words evenly.
|
24
|
+
# Where not all words can be shrunk evenly, the last words will be reduced by 1
|
25
|
+
# Until within the limit
|
26
|
+
# e.g.
|
27
|
+
# "Adelaide University".squash(30)
|
28
|
+
# => "Adelaide University"
|
29
|
+
# "Adelaide University".squash(10)
|
30
|
+
# => "Adela Univ"
|
31
|
+
# "Adelaide University".squash(7)
|
32
|
+
# => "Ade Uni"
|
33
|
+
# "Adelaide University".squash(3)
|
34
|
+
# => "AU"
|
35
|
+
# "Adelaide University".squash(2)
|
36
|
+
# => "AU"
|
37
|
+
# "Adelaide University".squash(1)
|
38
|
+
# => "A"
|
39
|
+
def squash(limit)
|
40
|
+
return self if size <= limit
|
41
|
+
|
42
|
+
words = split(' ')
|
43
|
+
|
44
|
+
# Return first letter of <limit> words
|
45
|
+
return words.first(limit).map{|w| w.chars.first}.join if (words.size * 2 - 1) >= limit
|
46
|
+
|
47
|
+
spaces = words.size - 1
|
48
|
+
word_char_min = (limit - spaces) / words.size
|
49
|
+
word_char_max = word_char_min + 1
|
50
|
+
|
51
|
+
words = words.map{|word| word[0..(word_char_max - 1)]}
|
52
|
+
|
53
|
+
words.reverse.each.with_index do |word, index|
|
54
|
+
letters_to_remove = words.join(' ').size - limit
|
55
|
+
|
56
|
+
letters_to_keep = if (last_case = (letters_to_remove <= (word.size - word_char_min)))
|
57
|
+
word.size - letters_to_remove # Removing final characters
|
58
|
+
else
|
59
|
+
word_char_min
|
60
|
+
end
|
61
|
+
|
62
|
+
# Replace word
|
63
|
+
words[words.size - index - 1] = word[0..(letters_to_keep - 1)]
|
64
|
+
|
65
|
+
break if last_case
|
66
|
+
end
|
67
|
+
|
68
|
+
words.join(' ')
|
69
|
+
end
|
70
|
+
|
71
|
+
|
72
|
+
def to_bool
|
73
|
+
return true if self == true || self =~ (/(true|t|yes|y|1)$/i)
|
74
|
+
return false if self == false || self.blank? || self =~ (/(false|f|no|n|0)$/i)
|
75
|
+
raise ArgumentError.new("invalid value for Boolean: \"#{self}\"")
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'ruby_core_extensions/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'ruby_core_extensions'
|
8
|
+
spec.version = RubyCoreExtensions::VERSION
|
9
|
+
spec.authors = ['Michael Noack', 'Alessandro Berardi']
|
10
|
+
spec.email = 'development@travellink.com.au'
|
11
|
+
spec.description = 'These are extensions from core ruby classes.'
|
12
|
+
spec.summary = 'Set of extensions to core ruby libraries used by TravelLink Technology.'
|
13
|
+
spec.homepage = 'http://github.com/sealink/ruby_core_extensions'
|
14
|
+
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
spec.files = `git ls-files`.split($/)
|
18
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
19
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
20
|
+
spec.require_paths = ["lib"]
|
21
|
+
|
22
|
+
spec.add_dependency 'activesupport', '>= 2.0'
|
23
|
+
spec.add_dependency 'tzinfo'
|
24
|
+
|
25
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
26
|
+
spec.add_development_dependency "rake"
|
27
|
+
spec.add_development_dependency 'rspec'
|
28
|
+
spec.add_development_dependency 'simplecov'
|
29
|
+
spec.add_development_dependency 'simplecov-rcov'
|
30
|
+
spec.add_development_dependency 'coveralls'
|
31
|
+
spec.add_development_dependency 'travis'
|
32
|
+
end
|
data/spec/array_spec.rb
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Array do
|
4
|
+
|
5
|
+
it "should allow converting all values to strings recursively" do
|
6
|
+
@now = Time.now
|
7
|
+
expect([1, 2, @now, [3, 4]].stringify_values_recursively).to eq ['1', '2', @now.to_s, ['3', '4']]
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should allow removing all blank values" do
|
11
|
+
a = [1, nil, 3, '']
|
12
|
+
a.compact_blank!
|
13
|
+
expect(a).to eq [1, 3]
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should allow removing all blank values recursively" do
|
17
|
+
a = [1, 2, [" Kan", {}], nil, {:a => "", :b => {}}, ["garoos", " "]]
|
18
|
+
a.recursive_compact_blank!
|
19
|
+
expect(a.join).to eq "12 Kangaroos"
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should allow verifying if all elements are blank recursively" do
|
23
|
+
expect(['',nil,[nil,['']]]).to be_recursive_blank
|
24
|
+
expect(['',nil,[nil,['',1]]]).to_not be_recursive_blank
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should allow converting to hash given a key" do
|
28
|
+
expect([1,2,3].hash_by(:ordinalize)).to eq({'1st' => 1, "2nd" => 2, "3rd" => 3})
|
29
|
+
expect([1,2,3].hash_by(:ordinalize, :to_s)).to eq({'1st' => '1', "2nd" => '2', "3rd" => '3'})
|
30
|
+
expect([1,2,3].hash_by(:ordinalize){ |v| v + 1 }).to eq({'1st' => 2, "2nd" => 3, "3rd" => 4})
|
31
|
+
expect([1,2,3].hash_by{|k| k * 2}).to eq({2 => 1, 4 => 2, 6 => 3})
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should allow executing blocks recursively" do
|
35
|
+
array = [1,[2,3],[4,[5,6],7,[8]],9,[[10]]]
|
36
|
+
result = []
|
37
|
+
array.recursively do |e|
|
38
|
+
result << e unless e.is_a?(Array)
|
39
|
+
end
|
40
|
+
expect(result).to eq [1,2,3,4,5,6,7,8,9,10]
|
41
|
+
end
|
42
|
+
|
43
|
+
it '#intersects?' do
|
44
|
+
array1 = [1, 2, 3]
|
45
|
+
array2 = [3, 4, 5]
|
46
|
+
array3 = [6, 7, 8]
|
47
|
+
|
48
|
+
expect(array1.intersects?(array2)).to be true
|
49
|
+
expect(array1.intersects?(array3)).to be false
|
50
|
+
expect(array2.intersects?(array3)).to be false
|
51
|
+
|
52
|
+
array1same = [1, 2, 3]
|
53
|
+
expect(array1.intersects?(array1same)).to be true
|
54
|
+
end
|
55
|
+
|
56
|
+
it '#first' do
|
57
|
+
expect(Array.first([])).to be nil
|
58
|
+
expect(Array.first([4, 2])).to eq 4
|
59
|
+
expect(Array.first(4)).to eq 4
|
60
|
+
end
|
61
|
+
|
62
|
+
it '#last' do
|
63
|
+
expect(Array.last([])).to be nil
|
64
|
+
expect(Array.last([4, 2])).to eq 2
|
65
|
+
expect(Array.last(4)).to eq 4
|
66
|
+
end
|
67
|
+
end
|
data/spec/class_spec.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
describe Array, 'compact' do
|
2
|
+
it 'should compact blank' do
|
3
|
+
a = [1, nil, 3]
|
4
|
+
a.compact_blank!
|
5
|
+
expect(a).to eq [1, 3]
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'should recursive compact blank' do
|
9
|
+
a = [1, nil, {:a => nil, :b => 2}]
|
10
|
+
a.recursive_compact_blank!
|
11
|
+
expect(a).to eq [1, {:b => 2}]
|
12
|
+
|
13
|
+
b = [1, nil, {:a => nil}]
|
14
|
+
b.recursive_compact_blank!
|
15
|
+
expect(b).to eq [1]
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe Hash, 'compact' do
|
20
|
+
it 'should compact' do
|
21
|
+
expect({:a => 1, :b => nil}.compact).to eq({:a => 1})
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'should compact!' do
|
25
|
+
a = {:a => 1, :b => nil}
|
26
|
+
a.compact!
|
27
|
+
expect(a).to eq({:a => 1})
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'should compact blank' do
|
31
|
+
expect({:a => 1, :b => ''}.compact_blank).to eq({:a => 1})
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'should compact blank!' do
|
35
|
+
a = {:a => 1, :b => ''}
|
36
|
+
a.compact_blank!
|
37
|
+
expect(a).to eq({:a => 1})
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'should recursive compact blank!' do
|
41
|
+
a = {:a => 1, :b => {:c => 1, :d => ''}}
|
42
|
+
a.recursive_compact_blank!
|
43
|
+
expect(a).to eq({:a => 1, :b => {:c => 1}})
|
44
|
+
|
45
|
+
a = {:a => 1, :b => {:c => [], :d => ''}}
|
46
|
+
a.recursive_compact_blank!
|
47
|
+
expect(a).to eq({:a => 1})
|
48
|
+
end
|
49
|
+
end
|