guerrilla_patch 2.6.2 → 2.7.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +50 -27
- data/VERSION +1 -1
- data/guerrilla_patch.gemspec +13 -8
- data/lib/guerrilla_patch/aggregate_by_type/aggregator.rb +54 -0
- data/lib/guerrilla_patch/aggregate_by_type/amount.rb +35 -0
- data/lib/guerrilla_patch/aggregate_by_type/divide_by_type.rb +14 -0
- data/lib/guerrilla_patch/kernel.rb +2 -2
- data/lib/guerrilla_patch.rb +1 -0
- data/spec/guerrilla_patch/aggregate_by_type/aggregator_spec.rb +93 -0
- data/spec/guerrilla_patch/aggregate_by_type/divide_by_type_spec.rb +26 -0
- metadata +19 -12
data/README.md
CHANGED
@@ -3,6 +3,55 @@ Guerrilla Patch
|
|
3
3
|
|
4
4
|
I am tired of hunting and tracking down my own monkey patches. Not to mention hassle of dragging them between projects. I figured gem is a remedy for this.
|
5
5
|
|
6
|
+
BigDecimal
|
7
|
+
-----------
|
8
|
+
Not using BigDecimal is asking for trouble, but using it is way too verbose:
|
9
|
+
|
10
|
+
```
|
11
|
+
amount = BigDecimal.new("100.10210")/BigDecimal.new(200.12)
|
12
|
+
```
|
13
|
+
|
14
|
+
It is more succint to put it like this:
|
15
|
+
|
16
|
+
```
|
17
|
+
amount = 100.10210.to_d/200.12
|
18
|
+
```
|
19
|
+
|
20
|
+
Allocate
|
21
|
+
---------
|
22
|
+
I belive allocate is missing from standard library. (At least I am unable to find it)
|
23
|
+
|
24
|
+
```
|
25
|
+
90.allocate_evenly(3) #=> [30, 30, 30]
|
26
|
+
100.allocate_evenly(3) #=> [33.33, 33.33, 33.34]
|
27
|
+
|
28
|
+
100.allocate([1.to_d/2, 1.to_d/2]) #=> [50, 50]
|
29
|
+
100.allocate([30, 30, 30]) #=> [33.33, 33.33, 33.34]
|
30
|
+
```
|
31
|
+
|
32
|
+
Divide Amount By Type
|
33
|
+
---------------
|
34
|
+
You can divide an amount by types. It uses allocate to prevent ±0.01 off errors.
|
35
|
+
|
36
|
+
```
|
37
|
+
ratios = { '1A' => 50, '1B' => 30, '1C' => 20 }
|
38
|
+
DivideByType.divide(ratios, 50)
|
39
|
+
==> {'1A' => 25, '1B' => 15, '1C' => 10}
|
40
|
+
```
|
41
|
+
|
42
|
+
Aggregation
|
43
|
+
------------
|
44
|
+
Support for aggregating hash values by type. You can add values and more interestingly subtract them.
|
45
|
+
|
46
|
+
```
|
47
|
+
amount = Aggregator.aggregate do |result|
|
48
|
+
result.add({ '1A' => 75 })
|
49
|
+
result.subtract({ '1A' => 25 })
|
50
|
+
end
|
51
|
+
==> 50, '1A' => 50
|
52
|
+
==
|
53
|
+
|
54
|
+
|
6
55
|
Short oneliners method definition
|
7
56
|
--------------------------------
|
8
57
|
Support for defining one liners with more succinct syntax (let, let_self)
|
@@ -54,36 +103,10 @@ end
|
|
54
103
|
|
55
104
|
Somehow for my convoluted brain the later reads better.
|
56
105
|
|
57
|
-
BigDecimal
|
58
|
-
-----------
|
59
|
-
Not using BigDecimal is asking for trouble, but using it is way too verbose:
|
60
|
-
|
61
|
-
```
|
62
|
-
amount = BigDecimal.new("100.10210")/BigDecimal.new(200.12)
|
63
|
-
```
|
64
|
-
|
65
|
-
It is more succint to put it like this:
|
66
|
-
|
67
|
-
```
|
68
|
-
amount = 100.10210.to_d/200.12
|
69
|
-
```
|
70
|
-
|
71
|
-
Allocate
|
72
|
-
---------
|
73
|
-
I belive allocate is missing from standard library. (At least I am unable to find it)
|
74
|
-
|
75
|
-
```
|
76
|
-
90.allocate_evenly(3) #=> [30, 30, 30]
|
77
|
-
100.allocate_evenly(3) #=> [33.33, 33.33, 33.34]
|
78
|
-
|
79
|
-
100.allocate([1.to_d/2, 1.to_d/2]) #=> [50, 50]
|
80
|
-
100.allocate([30, 30, 30]) #=> [33.33, 33.33, 33.34]
|
81
|
-
```
|
82
|
-
|
83
106
|
|
84
107
|
Contributing to guerrilla_patch
|
85
108
|
-------------------------------
|
86
|
-
|
109
|
+
|
87
110
|
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
|
88
111
|
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
|
89
112
|
* Fork the project
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.7.0
|
data/guerrilla_patch.gemspec
CHANGED
@@ -4,14 +4,14 @@
|
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
|
-
s.name =
|
8
|
-
s.version = "2.
|
7
|
+
s.name = %q{guerrilla_patch}
|
8
|
+
s.version = "2.7.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["drKreso"]
|
12
|
-
s.date =
|
13
|
-
s.description =
|
14
|
-
s.email =
|
12
|
+
s.date = %q{2012-10-10}
|
13
|
+
s.description = %q{I am tierd of hunting down monkey patches at large. Caging them inside this gem}
|
14
|
+
s.email = %q{kresimir.bojcic@gmail.com}
|
15
15
|
s.extra_rdoc_files = [
|
16
16
|
"LICENSE.txt",
|
17
17
|
"README.md"
|
@@ -27,18 +27,23 @@ Gem::Specification.new do |s|
|
|
27
27
|
"VERSION",
|
28
28
|
"guerrilla_patch.gemspec",
|
29
29
|
"lib/guerrilla_patch.rb",
|
30
|
+
"lib/guerrilla_patch/aggregate_by_type/aggregator.rb",
|
31
|
+
"lib/guerrilla_patch/aggregate_by_type/amount.rb",
|
32
|
+
"lib/guerrilla_patch/aggregate_by_type/divide_by_type.rb",
|
30
33
|
"lib/guerrilla_patch/allocate.rb",
|
31
34
|
"lib/guerrilla_patch/kernel.rb",
|
32
35
|
"lib/guerrilla_patch/string.rb",
|
36
|
+
"spec/guerrilla_patch/aggregate_by_type/aggregator_spec.rb",
|
37
|
+
"spec/guerrilla_patch/aggregate_by_type/divide_by_type_spec.rb",
|
33
38
|
"spec/guerrilla_patch/allocate_spec.rb",
|
34
39
|
"spec/guerrilla_patch/kernel_spec.rb",
|
35
40
|
"spec/guerrilla_patch/string_spec.rb"
|
36
41
|
]
|
37
|
-
s.homepage =
|
42
|
+
s.homepage = %q{http://github.com/drkreso/guerrilla_patch}
|
38
43
|
s.licenses = ["MIT"]
|
39
44
|
s.require_paths = ["lib"]
|
40
|
-
s.rubygems_version =
|
41
|
-
s.summary =
|
45
|
+
s.rubygems_version = %q{1.6.2}
|
46
|
+
s.summary = %q{Collection of monkey patches}
|
42
47
|
|
43
48
|
if s.respond_to? :specification_version then
|
44
49
|
s.specification_version = 3
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require_relative 'divide_by_type'
|
2
|
+
require_relative 'amount'
|
3
|
+
|
4
|
+
class Aggregator
|
5
|
+
def self.aggregate(&block)
|
6
|
+
agregator = Aggregator.new
|
7
|
+
block.call(agregator)
|
8
|
+
return Amount.new(agregator.total,agregator.total_by_type)
|
9
|
+
end
|
10
|
+
|
11
|
+
def add(amount)
|
12
|
+
total_list << Aggregator.prepare(amount)
|
13
|
+
end
|
14
|
+
|
15
|
+
def subtract(amount)
|
16
|
+
add(amount.negative)
|
17
|
+
end
|
18
|
+
|
19
|
+
def total
|
20
|
+
(by_type? ? total_by_type : total_list).sum_me
|
21
|
+
end
|
22
|
+
|
23
|
+
def total_by_type
|
24
|
+
Aggregator.agregate_by_type(total_list)
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def by_type?
|
30
|
+
return false if @total_list == []
|
31
|
+
|
32
|
+
total_list[0].class == Hash
|
33
|
+
end
|
34
|
+
|
35
|
+
def total_list
|
36
|
+
@total_list ||= []
|
37
|
+
end
|
38
|
+
|
39
|
+
#hey don't judge me, yes I know I am a bad man
|
40
|
+
def self.agregate_by_type(lista)
|
41
|
+
return {} if lista[0].class != Hash
|
42
|
+
|
43
|
+
result = lista.inject { |memo, el| self.merge_by_key(memo, el) }
|
44
|
+
(result.nil? ? {} : result).reject { |key, value| value == 0 }
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.merge_by_key(memo, el)
|
48
|
+
memo.merge( el ) { |key, old_v, new_v| old_v + new_v }
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.prepare(amount)
|
52
|
+
amount.class == Amount ? amount.divide : amount
|
53
|
+
end
|
54
|
+
end #Agregator
|
@@ -0,0 +1,35 @@
|
|
1
|
+
class Amount
|
2
|
+
attr_reader :value, :by_type
|
3
|
+
def initialize(value, by_type)
|
4
|
+
@value = value
|
5
|
+
@by_type = by_type
|
6
|
+
end
|
7
|
+
|
8
|
+
def ==(other)
|
9
|
+
self.value == other.value && self.by_type == other.by_type
|
10
|
+
end
|
11
|
+
|
12
|
+
def inspect
|
13
|
+
consists_of do |result|
|
14
|
+
result.add value_display
|
15
|
+
result.when(by_type_display != '') { ", #{by_type_display}"}
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def negative
|
20
|
+
Amount.new(-value, by_type)
|
21
|
+
end
|
22
|
+
|
23
|
+
def divide
|
24
|
+
DivideByType.divide(by_type, value)
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
def value_display
|
29
|
+
value.to_f
|
30
|
+
end
|
31
|
+
|
32
|
+
def by_type_display
|
33
|
+
by_type.map { |key, value| "#{key} => #{value.to_f}" }.join(", ")
|
34
|
+
end
|
35
|
+
end #Amount
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class DivideByType
|
2
|
+
def self.divide(ratios, amount)
|
3
|
+
return {} if amount == 0
|
4
|
+
ratios = { :no_division => 1 } if ratios == {}
|
5
|
+
|
6
|
+
Hash[ ratios.each_key.zip(allocate(amount, ratios.each_value)) ]
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
def self.allocate(amount, values)
|
11
|
+
total = values.reduce(:+)
|
12
|
+
amount.allocate( values.map { |amount| amount.to_d/total } )
|
13
|
+
end
|
14
|
+
end
|
@@ -45,7 +45,7 @@ module Kernel
|
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
48
|
-
#add
|
48
|
+
#add sum_me to array, with or without name
|
49
49
|
class Array
|
50
50
|
def sum_me(name = nil)
|
51
51
|
self.map(&name).reduce(0, :+)
|
@@ -65,7 +65,7 @@ class Fixnum
|
|
65
65
|
end
|
66
66
|
|
67
67
|
class Hash
|
68
|
-
def
|
68
|
+
def sum_me
|
69
69
|
self.each_value.reduce(0,:+)
|
70
70
|
end
|
71
71
|
end
|
data/lib/guerrilla_patch.rb
CHANGED
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'guerrilla_patch/aggregate_by_type/aggregator'
|
2
|
+
|
3
|
+
describe Aggregator do
|
4
|
+
it 'knows how to add regular number' do
|
5
|
+
amount = Aggregator.aggregate do |result|
|
6
|
+
result.add 1
|
7
|
+
result.add 2
|
8
|
+
end
|
9
|
+
|
10
|
+
amount.value.should == 3
|
11
|
+
amount.by_type.should == {}
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'knows how to subtract regular number' do
|
15
|
+
amount = Aggregator.aggregate do |result|
|
16
|
+
result.add 1
|
17
|
+
result.subtract 2
|
18
|
+
end
|
19
|
+
|
20
|
+
amount.value.should == -1
|
21
|
+
amount.by_type.should == {}
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'knows how to add amount with regular number' do
|
25
|
+
amount = Aggregator.aggregate do |result|
|
26
|
+
result.add Amount.new(1, {})
|
27
|
+
result.add Amount.new(2, {})
|
28
|
+
end
|
29
|
+
|
30
|
+
amount.value.should == 3
|
31
|
+
amount.by_type.should == { :no_division => 3 }
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'knows how to add amount of integer type' do
|
35
|
+
amount = Aggregator.aggregate do |result|
|
36
|
+
result.add Amount.new(1, {'1A' => 1})
|
37
|
+
result.add Amount.new(2, {'1B' => 1})
|
38
|
+
end
|
39
|
+
|
40
|
+
amount.value.should == 3
|
41
|
+
amount.by_type.should == { '1A' => 1, '1B' => 2}
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'knows how to add amount of bigdecimal type' do
|
45
|
+
amount = Aggregator.aggregate do |result|
|
46
|
+
result.add Amount.new(1.0.to_d, {'1A' => 1})
|
47
|
+
result.subtract Amount.new(2.2.to_d, {'1B' => 1})
|
48
|
+
end
|
49
|
+
|
50
|
+
amount.value.should == -1.2
|
51
|
+
amount.by_type.should == { '1A' => 1, '1B' => -2.2}
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'knows how to subtract floats amounts' do
|
55
|
+
amount = Aggregator.aggregate do |result|
|
56
|
+
result.add Amount.new(1.0, {'1A' => 1})
|
57
|
+
result.subtract Amount.new(2.2, {'1B' => 1})
|
58
|
+
end
|
59
|
+
|
60
|
+
amount.value.should == -1.2
|
61
|
+
amount.by_type.should == { '1A' => 1.0, '1B' => -2.2}
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'knows how to subtract integer amounts' do
|
65
|
+
amount = Aggregator.aggregate do |result|
|
66
|
+
result.add Amount.new(1, {'1A' => 1})
|
67
|
+
result.subtract Amount.new(2, {'1B' => 1})
|
68
|
+
end
|
69
|
+
|
70
|
+
amount.value.should == -1
|
71
|
+
amount.by_type.should == { '1A' => 1, '1B' => -2}
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'knows how to add by type' do
|
75
|
+
amount = Aggregator.aggregate do |result|
|
76
|
+
result.add({ '1A' => 75 })
|
77
|
+
result.add({ '1A' => 25 })
|
78
|
+
end
|
79
|
+
|
80
|
+
amount.value.should == 100
|
81
|
+
amount.by_type.should == { '1A' => 100 }
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'knows how to subtract by value' do
|
85
|
+
amount = Aggregator.aggregate do |result|
|
86
|
+
result.add({ '1A' => 75 })
|
87
|
+
result.subtract({ '1A' => 25 })
|
88
|
+
end
|
89
|
+
|
90
|
+
amount.value.should == 50
|
91
|
+
amount.by_type.should == { '1A' => 50 }
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'guerrilla_patch/aggregate_by_type/divide_by_type'
|
2
|
+
|
3
|
+
describe DivideByType do
|
4
|
+
before(:each) do
|
5
|
+
@ratios = { '1A' => 50, '1B' => 30, '1C' => 20 }
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'knows ratios' do
|
9
|
+
DivideByType.divide(@ratios, 50).should ==
|
10
|
+
{'1A' => 25, '1B' => 15, '1C' => 10}
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'knows ratios for negative values' do
|
14
|
+
DivideByType.divide(@ratios, -50).should ==
|
15
|
+
{'1A' => -25, '1B' => -15, '1C' => -10}
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'returns empty dividis for zero' do
|
19
|
+
DivideByType.divide(@ratios, 0).should == {}
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'knows how to divide without ratios' do
|
23
|
+
DivideByType.divide({}, 10).should == { :no_division => 10}
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: guerrilla_patch
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.7.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,12 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-10-10 00:00:00.000000000 +02:00
|
13
|
+
default_executable:
|
13
14
|
dependencies:
|
14
15
|
- !ruby/object:Gem::Dependency
|
15
16
|
name: rspec
|
16
|
-
requirement: &
|
17
|
+
requirement: &70268029827760 !ruby/object:Gem::Requirement
|
17
18
|
none: false
|
18
19
|
requirements:
|
19
20
|
- - ~>
|
@@ -21,10 +22,10 @@ dependencies:
|
|
21
22
|
version: 2.8.0
|
22
23
|
type: :development
|
23
24
|
prerelease: false
|
24
|
-
version_requirements: *
|
25
|
+
version_requirements: *70268029827760
|
25
26
|
- !ruby/object:Gem::Dependency
|
26
27
|
name: bundler
|
27
|
-
requirement: &
|
28
|
+
requirement: &70268029826660 !ruby/object:Gem::Requirement
|
28
29
|
none: false
|
29
30
|
requirements:
|
30
31
|
- - ~>
|
@@ -32,10 +33,10 @@ dependencies:
|
|
32
33
|
version: 1.0.0
|
33
34
|
type: :development
|
34
35
|
prerelease: false
|
35
|
-
version_requirements: *
|
36
|
+
version_requirements: *70268029826660
|
36
37
|
- !ruby/object:Gem::Dependency
|
37
38
|
name: jeweler
|
38
|
-
requirement: &
|
39
|
+
requirement: &70268029824840 !ruby/object:Gem::Requirement
|
39
40
|
none: false
|
40
41
|
requirements:
|
41
42
|
- - ~>
|
@@ -43,10 +44,10 @@ dependencies:
|
|
43
44
|
version: 1.6.4
|
44
45
|
type: :development
|
45
46
|
prerelease: false
|
46
|
-
version_requirements: *
|
47
|
+
version_requirements: *70268029824840
|
47
48
|
- !ruby/object:Gem::Dependency
|
48
49
|
name: rcov
|
49
|
-
requirement: &
|
50
|
+
requirement: &70268029823840 !ruby/object:Gem::Requirement
|
50
51
|
none: false
|
51
52
|
requirements:
|
52
53
|
- - ! '>='
|
@@ -54,7 +55,7 @@ dependencies:
|
|
54
55
|
version: '0'
|
55
56
|
type: :development
|
56
57
|
prerelease: false
|
57
|
-
version_requirements: *
|
58
|
+
version_requirements: *70268029823840
|
58
59
|
description: I am tierd of hunting down monkey patches at large. Caging them inside
|
59
60
|
this gem
|
60
61
|
email: kresimir.bojcic@gmail.com
|
@@ -74,12 +75,18 @@ files:
|
|
74
75
|
- VERSION
|
75
76
|
- guerrilla_patch.gemspec
|
76
77
|
- lib/guerrilla_patch.rb
|
78
|
+
- lib/guerrilla_patch/aggregate_by_type/aggregator.rb
|
79
|
+
- lib/guerrilla_patch/aggregate_by_type/amount.rb
|
80
|
+
- lib/guerrilla_patch/aggregate_by_type/divide_by_type.rb
|
77
81
|
- lib/guerrilla_patch/allocate.rb
|
78
82
|
- lib/guerrilla_patch/kernel.rb
|
79
83
|
- lib/guerrilla_patch/string.rb
|
84
|
+
- spec/guerrilla_patch/aggregate_by_type/aggregator_spec.rb
|
85
|
+
- spec/guerrilla_patch/aggregate_by_type/divide_by_type_spec.rb
|
80
86
|
- spec/guerrilla_patch/allocate_spec.rb
|
81
87
|
- spec/guerrilla_patch/kernel_spec.rb
|
82
88
|
- spec/guerrilla_patch/string_spec.rb
|
89
|
+
has_rdoc: true
|
83
90
|
homepage: http://github.com/drkreso/guerrilla_patch
|
84
91
|
licenses:
|
85
92
|
- MIT
|
@@ -95,7 +102,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
95
102
|
version: '0'
|
96
103
|
segments:
|
97
104
|
- 0
|
98
|
-
hash: -
|
105
|
+
hash: -1148938200376643015
|
99
106
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
100
107
|
none: false
|
101
108
|
requirements:
|
@@ -104,7 +111,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
104
111
|
version: '0'
|
105
112
|
requirements: []
|
106
113
|
rubyforge_project:
|
107
|
-
rubygems_version: 1.
|
114
|
+
rubygems_version: 1.6.2
|
108
115
|
signing_key:
|
109
116
|
specification_version: 3
|
110
117
|
summary: Collection of monkey patches
|