duck_puncher 4.2.1 → 4.2.2
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 +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
|