duck_puncher 4.2.1 → 4.2.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +25 -25
- data/lib/duck_puncher/defaults.rb +8 -2
- data/lib/duck_puncher/duck.rb +2 -1
- data/lib/duck_puncher/registration.rb +1 -1
- data/lib/duck_puncher/version.rb +1 -1
- data/lib/duck_puncher.rb +1 -1
- data/test/fixtures/test_classes.rb +42 -0
- data/test/lib/duck_puncher/enumerable_test.rb +19 -0
- data/test/test_helper.rb +2 -44
- metadata +3 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 65996bcd8666c6b83b5b5c3a71c6517b9ecc7d75
|
4
|
+
data.tar.gz: f1362ac2578ddcd74677066c9d168c267fee119a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3cc4e467436746ed770f32df6ab88d0b82b7134940f255cddc6b2899ba852641235afc9af94bd00a828d84bcd59b138656d6109d1ff5b3a7597d0f3a191ec45a
|
7
|
+
data.tar.gz: 223c5e24a33223540342be0ea2bbcfc969080e4bcd9e584e336325f869e39cf7bc88e3d3065107c2cc22b2d972eaa81ab03c7673731ff1438262533a9e7b3bf6
|
data/README.md
CHANGED
@@ -8,37 +8,37 @@ DuckPuncher provides an interface for administering __duck punches__ (a.k.a "mon
|
|
8
8
|
Default extensions:
|
9
9
|
|
10
10
|
```ruby
|
11
|
-
Enumerable
|
12
|
-
#m => `[].m(:to_s)`
|
13
|
-
#m! => `[].m!(:upcase)`
|
14
|
-
#mm => `[].mm(:sub, /[aeiou]/, '*')`
|
15
|
-
#mm! => `[].mm!(:sub, /[aeiou]/, '*')`
|
16
|
-
#except => `[].except('foo', 'bar')`
|
17
|
-
#map_keys => `[{id: 1
|
11
|
+
Enumerable (including Array, Set, Range, and Enumerator)
|
12
|
+
#m # => `[].m(:to_s)`
|
13
|
+
#m! # => `[].m!(:upcase)`
|
14
|
+
#mm # => `[].mm(:sub, /[aeiou]/, '*')`
|
15
|
+
#mm! # => `[].mm!(:sub, /[aeiou]/, '*')`
|
16
|
+
#except # => `[].except('foo', 'bar')`
|
17
|
+
#map_keys # => `[{id: 1}, {id: 2}].map_keys(:id)`
|
18
18
|
Hash
|
19
|
-
#dig => `{a: 1, b: {c: 2}}.dig(:b, :c)`
|
20
|
-
#compact => `{a: 1, b: nil}.compact` => {a: 1}
|
19
|
+
#dig # => `{a: 1, b: {c: 2}}.dig(:b, :c)` (Standard in Ruby >= 2.3)
|
20
|
+
#compact # => `{a: 1, b: nil}.compact` # => {a: 1}
|
21
21
|
Numeric
|
22
|
-
#to_currency => `25.245.to_currency` => 25.25
|
23
|
-
#to_duration => `10_000.to_duration` => '2 h 46 min'
|
24
|
-
#to_time_ago => `10_000.to_time_ago` => '2 hours ago'
|
25
|
-
#to_rad => `10.15.to_rad` => 0.17715091907742445
|
22
|
+
#to_currency # => `25.245.to_currency` # => 25.25
|
23
|
+
#to_duration # => `10_000.to_duration` # => '2 h 46 min'
|
24
|
+
#to_time_ago # => `10_000.to_time_ago` # => '2 hours ago'
|
25
|
+
#to_rad # => `10.15.to_rad` # => 0.17715091907742445
|
26
26
|
String
|
27
|
-
#pluralize => `'hour'.pluralize(2)` => "hours"
|
28
|
-
#underscore => `'
|
29
|
-
#to_boolean => `'1'.to_boolean` => true
|
30
|
-
#constantize => `'MiniTest::Test'.constantize` => MiniTest::Test
|
27
|
+
#pluralize # => `'hour'.pluralize(2)` # => "hours"
|
28
|
+
#underscore # => `'DJ::JSONStorage'.underscore` # => 'dj/json_storage'
|
29
|
+
#to_boolean # => `'1'.to_boolean` # => true
|
30
|
+
#constantize # => `'MiniTest::Test'.constantize` # => MiniTest::Test
|
31
31
|
Module
|
32
|
-
#local_methods => `Kernel.local_methods` returns the methods defined directly in the class + nested constants w/ methods
|
32
|
+
#local_methods # => `Kernel.local_methods` # => returns the methods defined directly in the class + nested constants w/ methods
|
33
33
|
Object
|
34
|
-
#clone! => `Object.new.clone!` => a deep clone of the object (using Marshal.dump)
|
35
|
-
#punch => `'duck'.punch` => a copy of 'duck' with String punches mixed in
|
36
|
-
#punch! => `'duck'.punch!` => destructive version applies extensions directly to the base object
|
37
|
-
#echo => `'duck'.echo.upcase` => spits out the caller and value of the object and returns the object
|
38
|
-
#track => `Object.new.track` => Traces methods calls to the object (requires [object_tracker](https://github.com/ridiculous/object_tracker), which it'll try to download)
|
34
|
+
#clone! # => `Object.new.clone!` # => a deep clone of the object (using Marshal.dump)
|
35
|
+
#punch # => `'duck'.punch` # => a copy of 'duck' with String punches mixed in
|
36
|
+
#punch! # => `'duck'.punch!` # => destructive version applies extensions directly to the base object
|
37
|
+
#echo # => `'duck'.echo.upcase` # => spits out the caller and value of the object and returns the object
|
38
|
+
#track # => `Object.new.track` # => Traces methods calls to the object (requires [object_tracker](https://github.com/ridiculous/object_tracker), which it'll try to download)
|
39
39
|
Method
|
40
|
-
#to_instruct => `Benchmark.method(:measure).to_instruct` returns the Ruby VM instruction sequence for the method
|
41
|
-
#to_source => `Benchmark.method(:measure).to_source` returns the method definition as a string
|
40
|
+
#to_instruct # => `Benchmark.method(:measure).to_instruct` returns the Ruby VM instruction sequence for the method
|
41
|
+
#to_source # => `Benchmark.method(:measure).to_source` returns the method definition as a string
|
42
42
|
```
|
43
43
|
|
44
44
|
## Usage
|
@@ -5,8 +5,14 @@ end
|
|
5
5
|
|
6
6
|
ducks = [
|
7
7
|
[String, DuckPuncher::Ducks::String],
|
8
|
-
[Enumerable, DuckPuncher::Ducks::Enumerable
|
9
|
-
|
8
|
+
[Enumerable, DuckPuncher::Ducks::Enumerable, {
|
9
|
+
# Re-include Enumerable in these classes to pick up the new extensions
|
10
|
+
after: proc {
|
11
|
+
[Array, Set, Range, Enumerator].each do |k|
|
12
|
+
DuckPuncher.logger.debug("Sending include to #{k} with Enumerable") and k.send(:include, Enumerable)
|
13
|
+
end
|
14
|
+
}
|
15
|
+
}],
|
10
16
|
[Numeric, DuckPuncher::Ducks::Numeric],
|
11
17
|
[Hash, DuckPuncher::Ducks::Hash],
|
12
18
|
[Object, DuckPuncher::Ducks::Object],
|
data/lib/duck_puncher/duck.rb
CHANGED
@@ -19,7 +19,8 @@ module DuckPuncher
|
|
19
19
|
# @option options [Symbol,String] :method Specifies if the methods should be included or prepended (:include)
|
20
20
|
# @return [Class] The class that was just punched
|
21
21
|
def punch(opts = {})
|
22
|
-
|
22
|
+
opts = options.merge opts
|
23
|
+
targets = Array(opts[:target] || self.target)
|
23
24
|
targets.each do |target|
|
24
25
|
options[:before].call(target) if options[:before]
|
25
26
|
target.extend Usable
|
@@ -4,7 +4,7 @@ module DuckPuncher
|
|
4
4
|
def register(target, *mods)
|
5
5
|
options = mods.last.is_a?(Hash) ? mods.pop : {}
|
6
6
|
target = DuckPuncher.lookup_constant target
|
7
|
-
Ducks.list[target] = [] unless Ducks.list.key?(target)
|
7
|
+
Ducks.list[target] = Set.new [] unless Ducks.list.key?(target)
|
8
8
|
Array(mods).each do |mod|
|
9
9
|
duck = Duck.new target, mod, options
|
10
10
|
Ducks.list[target] << duck
|
data/lib/duck_puncher/version.rb
CHANGED
data/lib/duck_puncher.rb
CHANGED
@@ -40,7 +40,7 @@ module DuckPuncher
|
|
40
40
|
classes.each do |klass|
|
41
41
|
klass = lookup_constant(klass)
|
42
42
|
Ducks[klass].sort.each do |duck|
|
43
|
-
punches = Array(options[:only] || Ducks::Module.instance_method(:local_methods).bind(duck.mod).call)
|
43
|
+
punches = Array(options[:only] || duck.options[:only] || Ducks::Module.instance_method(:local_methods).bind(duck.mod).call)
|
44
44
|
options[:target] = klass
|
45
45
|
logger.info %Q(#{klass}#{" <-- #{duck.mod.name}#{punches}" if punches.any?})
|
46
46
|
unless duck.punch(options)
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module CustomPunch
|
2
|
+
def talk
|
3
|
+
p self
|
4
|
+
self
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
module CustomPunch2
|
9
|
+
def quack
|
10
|
+
'quack'
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
module CustomPunch3
|
15
|
+
def wobble
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
module ModWithOverride
|
20
|
+
def talk
|
21
|
+
'talk is cheap'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
module ModWithNestedMod
|
26
|
+
def instance_method_1
|
27
|
+
end
|
28
|
+
|
29
|
+
module ClassMethods
|
30
|
+
def class_method_1
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
class Animal
|
36
|
+
end
|
37
|
+
|
38
|
+
class Dog < Animal
|
39
|
+
end
|
40
|
+
|
41
|
+
class Kaia < Dog
|
42
|
+
end
|
@@ -17,6 +17,25 @@ class EnumerableTest < MiniTest::Test
|
|
17
17
|
assert_equal subject.object_id, subject.m!(:upcase).object_id
|
18
18
|
end
|
19
19
|
|
20
|
+
def test_m_with_range
|
21
|
+
@subject = ('a'..'f')
|
22
|
+
assert_equal %w[A B C D E F], @subject.punch.m(:upcase)
|
23
|
+
assert_equal %w[A B C D E F], @subject.punch!.m(:upcase)
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_m_with_enum
|
27
|
+
@subject = ('A'..'F').to_enum
|
28
|
+
assert_equal %w[B C D E F G], @subject.punch.m(:next)
|
29
|
+
assert_equal %w[B C D E F G], @subject.punch!.m(:next)
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_mm_with_set
|
33
|
+
@subject = Set.new %w[a b c d e f]
|
34
|
+
assert_equal %w[A B C D E F], @subject.punch.m(:upcase)
|
35
|
+
assert_equal %w[A B C D E F], @subject.punch!.m(:upcase)
|
36
|
+
assert_equal %w[B C D E F G], @subject.punch!.m!(:upcase).m(:next)
|
37
|
+
end
|
38
|
+
|
20
39
|
def test_mm_with_two_args
|
21
40
|
subject.punch!
|
22
41
|
assert_equal subject.map { |x| x.prepend('btn-') }, subject.mm(:prepend, 'btn-')
|
data/test/test_helper.rb
CHANGED
@@ -2,50 +2,8 @@ require 'minitest'
|
|
2
2
|
require 'minitest/autorun'
|
3
3
|
require 'minitest/reporters'
|
4
4
|
require 'duck_puncher'
|
5
|
+
require_relative 'fixtures/test_classes'
|
5
6
|
|
6
7
|
Minitest::Reporters.use!
|
7
8
|
|
8
|
-
DuckPuncher.logger.level = Logger::
|
9
|
-
|
10
|
-
module CustomPunch
|
11
|
-
def talk
|
12
|
-
p self
|
13
|
-
self
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
module CustomPunch2
|
18
|
-
def quack
|
19
|
-
'quack'
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
module CustomPunch3
|
24
|
-
def wobble
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
module ModWithOverride
|
29
|
-
def talk
|
30
|
-
'talk is cheap'
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
module ModWithNestedMod
|
35
|
-
def instance_method_1
|
36
|
-
end
|
37
|
-
|
38
|
-
module ClassMethods
|
39
|
-
def class_method_1
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
class Animal
|
45
|
-
end
|
46
|
-
|
47
|
-
class Dog < Animal
|
48
|
-
end
|
49
|
-
|
50
|
-
class Kaia < Dog
|
51
|
-
end
|
9
|
+
DuckPuncher.logger.level = Logger::DEBUG
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: duck_puncher
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.2.
|
4
|
+
version: 4.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Buckley
|
@@ -123,6 +123,7 @@ files:
|
|
123
123
|
- lib/duck_puncher/registration.rb
|
124
124
|
- lib/duck_puncher/utilities.rb
|
125
125
|
- lib/duck_puncher/version.rb
|
126
|
+
- test/fixtures/test_classes.rb
|
126
127
|
- test/fixtures/wut.rb
|
127
128
|
- test/lib/duck_puncher/enumerable_test.rb
|
128
129
|
- test/lib/duck_puncher/hash_test.rb
|
@@ -158,6 +159,7 @@ signing_key:
|
|
158
159
|
specification_version: 4
|
159
160
|
summary: Administer precision extensions (a.k.a "punches") to your favorite Ruby classes
|
160
161
|
test_files:
|
162
|
+
- test/fixtures/test_classes.rb
|
161
163
|
- test/fixtures/wut.rb
|
162
164
|
- test/lib/duck_puncher/enumerable_test.rb
|
163
165
|
- test/lib/duck_puncher/hash_test.rb
|