ruby_core_extensions 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|