active_object 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'active_object/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "active_object"
8
+ spec.version = ActiveObject::VERSION
9
+ spec.authors = ["Juan Gomez"]
10
+ spec.email = ["j.gomez@drexed.com"]
11
+ spec.summary = %q{Commonly used ruby object helpers.}
12
+ spec.description = %q{Class extensions of commonly used ruby object helpers.}
13
+ spec.homepage = "https://github.com/drexed/active_object"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler"
22
+ spec.add_development_dependency "coveralls"
23
+ spec.add_development_dependency "rake"
24
+ spec.add_development_dependency "rspec"
25
+ end
@@ -0,0 +1,9 @@
1
+ require 'active_object/version'
2
+ require 'active_object/array'
3
+ require 'active_object/enumerable'
4
+ require 'active_object/hash'
5
+ require 'active_object/integer'
6
+ require 'active_object/numeric'
7
+ require 'active_object/object'
8
+ require 'active_object/string'
9
+ require 'active_object/time'
@@ -0,0 +1,118 @@
1
+ class Array
2
+
3
+ def delete_first
4
+ self[1..-1]
5
+ end
6
+
7
+ def delete_last
8
+ self[0...-1]
9
+ end
10
+
11
+ unless method_defined?(:from)
12
+ def from(position)
13
+ self[position, size] || []
14
+ end
15
+ end
16
+
17
+ def groups(number)
18
+ return([]) if number <= 0
19
+ n, r = size.divmod(number)
20
+ collection = (0..(n - 1)).collect { |i| self[(i * number), number] }
21
+ r > 0 ? collection << self[-r, r] : collection
22
+ end
23
+
24
+ unless method_defined?(:in_groups)
25
+ def in_groups(number, fill_with=nil)
26
+ collection_size = size
27
+ division = collection_size.div(number)
28
+ modulo = collection_size % number
29
+
30
+ collection = []
31
+ start = 0
32
+ number.times do |i|
33
+ grouping = division + (modulo > 0 && modulo > i ? 1 : 0)
34
+ collection << last_group = slice(start, grouping)
35
+ last_group << fill_with if fill_with != false && modulo > 0 && grouping == division
36
+ start += grouping
37
+ end
38
+
39
+ block_given? ? collection.each { |g| yield(g) } : collection
40
+ end
41
+ end
42
+
43
+ unless method_defined?(:in_groups_of)
44
+ def in_groups_of(number, fill_with=nil)
45
+ if number.to_i <= 0
46
+ raise ArgumentError,
47
+ "Group size must be a positive integer, was #{number.inspect}"
48
+ end
49
+
50
+ if fill_with == false
51
+ collection = self
52
+ else
53
+ padding = (number - size % number) % number
54
+ collection = dup.concat(Array.new(padding, fill_with))
55
+ end
56
+
57
+ block_given? ? collection.each_slice(number) { |slice| yield(slice) } : collection.each_slice(number).to_a
58
+ end
59
+ end
60
+
61
+ unless method_defined?(:split)
62
+ def split(number=nil)
63
+ if block_given?
64
+ inject([[]]) do |results, element|
65
+ yield(element) ? results << [] : results.last << element
66
+ results
67
+ end
68
+ else
69
+ results, arr = [[]], dup
70
+ until arr.empty?
71
+ if (idx = arr.index(number))
72
+ results.last.concat(arr.shift(idx))
73
+ arr.shift
74
+ results << []
75
+ else
76
+ results.last.concat(arr.shift(arr.size))
77
+ end
78
+ end
79
+ results
80
+ end
81
+ end
82
+ end
83
+
84
+ def strip
85
+ reject { |v| v.blank? }
86
+ end
87
+
88
+ unless method_defined?(:to)
89
+ def to(position)
90
+ position >= 0 ? first(position + 1) : self[0..position]
91
+ end
92
+ end
93
+
94
+ unless method_defined?(:to_sentence)
95
+ def to_sentence(options={})
96
+ options.assert_valid_keys(:words_connector, :two_words_connector, :last_word_connector)
97
+
98
+ default_connectors = {
99
+ words_connector: ', ',
100
+ two_words_connector: ' and ',
101
+ last_word_connector: ', and '
102
+ }
103
+ options = default_connectors.merge!(options)
104
+
105
+ case size
106
+ when 0
107
+ ''
108
+ when 1
109
+ self[0].to_s.dup
110
+ when 2
111
+ "#{self[0]}#{options[:two_words_connector]}#{self[1]}"
112
+ else
113
+ "#{self[0...-1].join(options[:words_connector])}#{options[:last_word_connector]}#{self[-1]}"
114
+ end
115
+ end
116
+ end
117
+
118
+ end
@@ -0,0 +1,172 @@
1
+ module Enumerable
2
+
3
+ def difference(identity=0, &block)
4
+ if block_given?
5
+ map(&block).difference(identity)
6
+ else
7
+ inject { |d,v| d - v } || identity
8
+ end
9
+ end
10
+
11
+ def divisible(identity=0, &block)
12
+ if block_given?
13
+ map(&block).divisible(identity)
14
+ else
15
+ inject { |d,v| d / v } || identity
16
+ end
17
+ end
18
+
19
+ def drop_last(n)
20
+ collection_size = to_a.size
21
+ return(self) if n > collection_size
22
+ self[0...(collection_size - n)]
23
+ end
24
+
25
+ def drop_last_if
26
+ return(to_enum(:drop_last_if)) unless block_given?
27
+
28
+ result = []
29
+ dropping = true
30
+ reverse_each do |value|
31
+ result.unshift(value) unless dropping &&= yield(value)
32
+ end
33
+ result
34
+ end
35
+
36
+ def exactly?(n)
37
+ found_count = 0
38
+ block_given? ? each { |*o| found_count += 1 if yield(*o) } : each { |o| found_count += 1 if o }
39
+ (found_count > n) ? false : n == found_count
40
+ end
41
+
42
+ unless method_defined?(:exclude?)
43
+ def exclude?(object)
44
+ !include?(object)
45
+ end
46
+ end
47
+
48
+ def exponential(identity=0, &block)
49
+ if block_given?
50
+ map(&block).exponential(identity)
51
+ else
52
+ inject { |d,v| d ** v } || identity
53
+ end
54
+ end
55
+
56
+ def frequencies
57
+ each_with_object(Hash.new(0)) { |e, a| a[e] += 1 }
58
+ end
59
+
60
+ unless method_defined?(:many?)
61
+ def many?
62
+ found_count = 0
63
+ if block_given?
64
+ any? do |v|
65
+ found_count += 1 if yield v
66
+ found_count > 1
67
+ end
68
+ else
69
+ any? { (found_count += 1) > 1 }
70
+ end
71
+ end
72
+ end
73
+
74
+ def max(identity=0)
75
+ size > 0 ? sort.last : identity
76
+ end
77
+
78
+ def min(identity=0)
79
+ size > 0 ? sort.first : identity
80
+ end
81
+
82
+ def mean(identity=0)
83
+ return(identity) unless size > 0
84
+ collection_size = size
85
+ sum / collection_size.to_f
86
+ end
87
+
88
+ def median(identity=0)
89
+ collection_size = size
90
+ collection_sorted = sort
91
+
92
+ return(identity) unless collection_size > 0
93
+
94
+ if (collection_size % 2).zero?
95
+ (collection_sorted[(collection_size / 2.0) -1.0] + collection_sorted[collection_size / 2.0]) / 2.0
96
+ else
97
+ collection_sorted[collection_size / 2.0]
98
+ end
99
+ end
100
+
101
+ def mode(identity=0)
102
+ return(identity) unless size > 0
103
+
104
+ frequency_distribution = inject(Hash.new(0)) { |h,v| h[v] += 1; h }
105
+ frequency_top_two = frequency_distribution.sort { |k,v| v[1] <=> k[1] }.take(2)
106
+
107
+ if frequency_top_two.size == 1
108
+ frequency_top_two.first.first
109
+ elsif frequency_top_two.first.last == frequency_top_two.last.last
110
+ nil
111
+ else
112
+ frequency_top_two.first.first
113
+ end
114
+ end
115
+
116
+ def multiple(identity=0, &block)
117
+ if block_given?
118
+ map(&block).multiple(identity)
119
+ else
120
+ inject { |d,v| d * v } || identity
121
+ end
122
+ end
123
+
124
+ def range(identity=0)
125
+ return(identity) unless size > 0
126
+ collection_sorted = sort
127
+ collection_sorted.last - collection_sorted.first
128
+ end
129
+
130
+ def several?
131
+ found_count = 0
132
+ block_given? ? each { |*o| found_count += 1 if yield(*o) } : each { |o| found_count += 1 if o }
133
+ (found_count > 1) ? true : false
134
+ end
135
+
136
+ def standard_deviation(identity=0)
137
+ return(identity) if size < 2
138
+ Math.sqrt(variance)
139
+ end
140
+
141
+ unless method_defined?(:sum)
142
+ def sum(identity=0, &block)
143
+ if block_given?
144
+ map(&block).sum(identity)
145
+ else
146
+ inject { |s,v| s + v } || identity
147
+ end
148
+ end
149
+ end
150
+
151
+ def take_last(n)
152
+ collection_size = to_a.size
153
+ return(self) if n > collection_size
154
+ self[(collection_size - n)..-1]
155
+ end
156
+
157
+ def take_last_if
158
+ return(to_enum(:take_last_if)) unless block_given?
159
+
160
+ result = []
161
+ reverse_each { |e| yield(e) ? result.unshift(e) : break }
162
+ result
163
+ end
164
+
165
+ def variance(identity=0)
166
+ collection_size = size
167
+ return(identity) if collection_size <= 1
168
+ sum = inject(0.0) { |s,v| s + (v - mean) ** 2.0 }
169
+ sum / (collection_size.to_f - 1.0)
170
+ end
171
+
172
+ end
@@ -0,0 +1,203 @@
1
+ class Hash
2
+
3
+ unless method_defined?(:assert_valid_keys)
4
+ def assert_valid_keys(*valid_keys)
5
+ valid_keys.flatten!
6
+ each_key do |k|
7
+ unless valid_keys.include?(k)
8
+ raise ArgumentError, "Unknown key: #{k.inspect}. Valid keys are: #{valid_keys.map(&:inspect).join(', ')}"
9
+ end
10
+ end
11
+ end
12
+ end
13
+
14
+ unless method_defined?(:compact)
15
+ def compact
16
+ select { |k,v| !v.nil? }
17
+ end
18
+ end
19
+
20
+ unless method_defined?(:compact!)
21
+ def compact!
22
+ reject! { |k,v| v.nil? }
23
+ end
24
+ end
25
+
26
+ unless method_defined?(:deep_merge)
27
+ def deep_merge(other_hash, &block)
28
+ dup.deep_merge!(other_hash, &block)
29
+ end
30
+ end
31
+
32
+ unless method_defined?(:deep_merge!)
33
+ def deep_merge!(other_hash, &block)
34
+ other_hash.each_pair do |current_key, other_value|
35
+ this_value = self[current_key]
36
+
37
+ self[current_key] = if this_value.is_a?(Hash) && other_value.is_a?(Hash)
38
+ this_value.deep_merge(other_value, &block)
39
+ else
40
+ block_given? && key?(current_key) ? block.call(current_key, this_value, other_value) : other_value
41
+ end
42
+ end
43
+ self
44
+ end
45
+ end
46
+
47
+ unless method_defined?(:except)
48
+ def except(*keys)
49
+ dup.except!(*keys)
50
+ end
51
+ end
52
+
53
+ unless method_defined?(:except!)
54
+ def except!(*keys)
55
+ keys.each { |k| delete(k) }
56
+ self
57
+ end
58
+ end
59
+
60
+ def nillify
61
+ dup.nillify!
62
+ end
63
+
64
+ def nillify!
65
+ each do |k, v|
66
+ if !v.nil? && ((v.respond_to?(:blank?) && v.blank?) || (v.respond_to?(:to_s) && v.to_s.blank?))
67
+ self[k] = nil
68
+ end
69
+ end
70
+ end
71
+
72
+ unless method_defined?(:only)
73
+ def only(*keys)
74
+ dup.only!(*keys)
75
+ end
76
+ end
77
+
78
+ unless method_defined?(:only!)
79
+ def only!(*args)
80
+ hash = {}
81
+ args.each {|k| hash[k] = self[k] if self.has_key?(k) }
82
+ hash
83
+ end
84
+ end
85
+
86
+ def rename_keys(*args)
87
+ dup.rename_keys!(*args)
88
+ end
89
+
90
+ def rename_keys!(*args)
91
+ keys = Hash[*args.flatten]
92
+ keys.each { |k, v| self[v] = delete(k) if self[k] }
93
+ self
94
+ end
95
+
96
+ unless method_defined?(:reverse_merge)
97
+ def reverse_merge(other_hash)
98
+ other_hash.merge(self)
99
+ end
100
+ end
101
+
102
+ unless method_defined?(:reverse_merge!)
103
+ def reverse_merge!(other_hash)
104
+ merge!(other_hash) { |k,l,r| l }
105
+ end
106
+ end
107
+
108
+ unless method_defined?(:slice)
109
+ def slice(*keys)
110
+ keys.each_with_object(self.class.new) { |k, h| h[k] = self[k] if has_key?(k) }
111
+ end
112
+ end
113
+
114
+ unless method_defined?(:slice!)
115
+ def slice!(*keys)
116
+ omit = slice(*self.keys - keys)
117
+ hash = slice(*keys)
118
+
119
+ hash.default = default
120
+ hash.default_proc = default_proc if default_proc
121
+
122
+ replace(hash)
123
+ omit
124
+ end
125
+ end
126
+
127
+ unless method_defined?(:stringify_keys)
128
+ def stringify_keys
129
+ dup.stringify_keys!
130
+ end
131
+ end
132
+
133
+ unless method_defined?(:stringify_keys!)
134
+ def stringify_keys!
135
+ inject({}) do |options,(k,v)|
136
+ options[k.to_s] = v
137
+ options
138
+ end
139
+ end
140
+ end
141
+
142
+ def strip
143
+ select { |k,v| !v.blank? }
144
+ end
145
+
146
+ def strip!
147
+ reject! { |k,v| v.blank? }
148
+ end
149
+
150
+ unless method_defined?(:symbolize_keys)
151
+ def symbolize_keys
152
+ dup.symbolize_keys!
153
+ end
154
+ end
155
+
156
+ unless method_defined?(:symbolize_keys!)
157
+ def symbolize_keys!
158
+ inject({}) do |options, (k,v)|
159
+ options[(k.to_sym rescue k) || k] = v
160
+ options
161
+ end
162
+ end
163
+ end
164
+
165
+ def symbolize_and_underscore_keys
166
+ dup.symbolize_and_underscore_keys!
167
+ end
168
+
169
+ def symbolize_and_underscore_keys!
170
+ inject({}) do |options, (k,v)|
171
+ options[(k.to_s.gsub(" ", "_").underscore.to_sym rescue k) || k] = v
172
+ options
173
+ end
174
+ end
175
+
176
+ unless method_defined?(:transform_keys)
177
+ def transform_keys(&block)
178
+ dup.transform_keys!(&block)
179
+ end
180
+ end
181
+
182
+ unless method_defined?(:transform_keys!)
183
+ def transform_keys!(&block)
184
+ return(enum_for(:transform_keys!)) unless block_given?
185
+ keys.each { |k| self[yield(k)] = delete(k) }
186
+ self
187
+ end
188
+ end
189
+
190
+ unless method_defined?(:transform_values)
191
+ def transform_values(&block)
192
+ dup.transform_values!(&block)
193
+ end
194
+ end
195
+
196
+ unless method_defined?(:transform_values!)
197
+ def transform_values!(&block)
198
+ return(enum_for(:transform_values!)) unless block_given?
199
+ each { |k,v| self[k] = yield(v) }
200
+ end
201
+ end
202
+
203
+ end