guerrilla_patch 2.6.2 → 2.7.0
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.
- 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
|