duck_puncher 2.11.0 → 2.12.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.
- checksums.yaml +4 -4
- data/README.md +49 -21
- data/bin/console +2 -0
- data/lib/duck_puncher.rb +3 -6
- data/lib/duck_puncher/duck.rb +1 -1
- data/lib/duck_puncher/ducks.rb +1 -1
- data/lib/duck_puncher/gem_installer.rb +1 -1
- data/lib/duck_puncher/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5df7873691d0800251c6f01efa662ff8ffe5951f
|
4
|
+
data.tar.gz: 8143c677f0dab3351ed2f19c94b575efc6058682
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bb8741aacf58c8f481df8b7976fc263f128d2d27c56deab4b734f08dab0400ed9a8e48b592d0e692f2d25d0f223b07ca64d3a3002ea898d7956eb6d83747be01
|
7
|
+
data.tar.gz: 43e29a239f7ca340ccc0aa64abd36097d81e3ab6088866eb28bd9b6f6dfd395cf0b8b9e46ae38ca098f52b639a3e6ad9245514607bfb95f8fb9665fab98ab450
|
data/README.md
CHANGED
@@ -17,18 +17,17 @@ Numeric #to_currency => `25.245.to_currency` => 25.25
|
|
17
17
|
String #pluralize => `'hour'.pluralize(2)` => "hours"
|
18
18
|
#underscore => `'DuckPuncher::JSONStorage'.underscore` => 'duck_puncher/json_storage'
|
19
19
|
Object #clone! => `Object.new.clone!` => a deep clone of the object (using Marshal.dump)
|
20
|
-
#punch => `'duck'.punch` => a copy of 'duck' with
|
20
|
+
#punch => `'duck'.punch` => a copy of 'duck' with String punches mixed in
|
21
21
|
Method #to_instruct => `Benchmark.method(:measure).to_instruct` returns the Ruby VM instruction sequence for the method
|
22
22
|
#to_source => `Benchmark.method(:measure).to_source` returns the method definition as a string
|
23
23
|
```
|
24
24
|
|
25
25
|
## Tactical punches
|
26
26
|
|
27
|
-
|
27
|
+
Punch only certain methods onto a duck:
|
28
28
|
|
29
29
|
```ruby
|
30
30
|
>> DuckPuncher.punch! :Numeric, only: [:to_currency, :to_duration]
|
31
|
-
WARN: Punching [:to_currency, :to_duration] onto Numeric
|
32
31
|
=> nil
|
33
32
|
>> 100.to_currency '$'
|
34
33
|
=> "$100.00"
|
@@ -44,11 +43,8 @@ NoMethodError: undefined method `to_time_ago' for 100:Fixnum
|
|
44
43
|
|
45
44
|
## Usage
|
46
45
|
|
47
|
-
Ducks need to be _loaded_ before they can be punched! Maybe put this in an initializer:
|
48
|
-
|
49
46
|
```ruby
|
50
|
-
#
|
51
|
-
DuckPuncher.punch_all! # => punches all the ducks forever
|
47
|
+
DuckPuncher.punch_all! # => punches all registered ducks
|
52
48
|
DuckPuncher.punch! :Hash, :Object # => only punches the Hash and Object ducks
|
53
49
|
DuckPuncher.punch! :Object, only: :punch # => only opens a can of whoop ass! Define one method to rule them all
|
54
50
|
```
|
@@ -79,9 +75,40 @@ Because `DuckPuncher` extends the amazing [Usable](https://github.com/ridiculous
|
|
79
75
|
## Registering custom punches
|
80
76
|
|
81
77
|
DuckPuncher allows you to utilize the `punch` interface to decorate any kind of object with your own punches. Simply call
|
82
|
-
`.register` with the name of your module
|
78
|
+
`.register` with the name of your module.
|
79
|
+
|
80
|
+
### Punching your own duck
|
81
|
+
```ruby
|
82
|
+
class User < Struct.new(:name)
|
83
|
+
end
|
84
|
+
|
85
|
+
module Billable
|
86
|
+
def perform(amt)
|
87
|
+
puts "Attempting to bill #{name} for $#{amt}"
|
88
|
+
fail Errno::ENOENT
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
module Retryable
|
93
|
+
def perform_with_retry(*args, retries: 3)
|
94
|
+
perform *args
|
95
|
+
rescue Errno::ENOENT
|
96
|
+
puts 'retrying'
|
97
|
+
retry if (retries -= 1) > 0
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
DuckPuncher.register :Billable
|
102
|
+
DuckPuncher.register :Retryable
|
103
|
+
DuckPuncher.punch! :Object, only: :punch
|
104
|
+
|
105
|
+
user = User.new('Ryan').punch(:Billable).punch(:Retryable)
|
106
|
+
user.perform_with_retry(19.99)
|
107
|
+
```
|
83
108
|
|
109
|
+
### Punching core ducks
|
84
110
|
```ruby
|
111
|
+
# Example punches
|
85
112
|
module Donald
|
86
113
|
def tap_tap
|
87
114
|
p self
|
@@ -94,33 +121,30 @@ module Daisy
|
|
94
121
|
"Hi, I'm Daisy"
|
95
122
|
end
|
96
123
|
end
|
97
|
-
|
98
|
-
DuckPuncher.register :Donald, class: 'Array', if: -> { 'some condition' }
|
99
|
-
DuckPuncher.register :Daisy, class: 'Array'
|
100
124
|
```
|
101
125
|
|
102
|
-
|
103
|
-
and will be used to configure punches.
|
104
|
-
|
105
|
-
Activate a custom punch:
|
126
|
+
When punching a class, the `:class` option is required when registering:
|
106
127
|
|
107
128
|
```ruby
|
129
|
+
DuckPuncher.register :Donald, class: 'Array'
|
108
130
|
DuckPuncher.punch! :Donald
|
109
131
|
[].tap_tap
|
110
|
-
# or
|
111
|
-
DuckPuncher.punch! :Object, only: :punch
|
112
|
-
[].punch(:Donald).tap_tap
|
113
132
|
```
|
114
133
|
|
115
|
-
|
134
|
+
When punching instances, the `:class` option can be omitted, but the name of the punch is required:
|
116
135
|
|
117
136
|
```ruby
|
118
137
|
DuckPuncher.punch! :Object, only: :punch
|
138
|
+
DuckPuncher.register :Donald
|
139
|
+
DuckPuncher.register :Daisy
|
119
140
|
ducks = [].punch(:Donald).punch(:Daisy)
|
120
141
|
ducks.tap_tap
|
121
142
|
ducks.quack
|
122
143
|
```
|
123
144
|
|
145
|
+
The `register` method takes the same options as [Duck#initialize](https://github.com/ridiculous/duck_puncher/blob/master/lib/duck_puncher/duck.rb#L11)
|
146
|
+
and will be used to configure punches.
|
147
|
+
|
124
148
|
## Experimental
|
125
149
|
|
126
150
|
__Object#require!__ will try to require a gem, or, if it's not found, then _download_ it! It will also keep track of any
|
@@ -136,7 +160,6 @@ LoadError: cannot load such file -- pry
|
|
136
160
|
from (irb):1
|
137
161
|
from bin/console:10:in `<main>'
|
138
162
|
>> DuckPuncher.punch! :Object, only: :require!
|
139
|
-
WARN: Punching require! onto Object
|
140
163
|
=> nil
|
141
164
|
>> require! 'pry'
|
142
165
|
Fetching: method_source-0.8.2.gem (100%)
|
@@ -196,5 +219,10 @@ Duck.track
|
|
196
219
|
|
197
220
|
* Fork it
|
198
221
|
* Run tests with `rake`
|
199
|
-
* Start an IRB console that already has all your ducks in a row `bin/console`
|
222
|
+
* Start an IRB console that already has all your ducks in a row: `bin/console`
|
223
|
+
* Start an IRB console without punching ducks: `PUNCH=no bin/console`
|
200
224
|
* Make changes and submit a PR to [https://github.com/ridiculous/duck_puncher](https://github.com/ridiculous/duck_puncher)
|
225
|
+
|
226
|
+
## License
|
227
|
+
|
228
|
+
MIT
|
data/bin/console
CHANGED
data/lib/duck_puncher.rb
CHANGED
@@ -56,7 +56,7 @@ module DuckPuncher
|
|
56
56
|
end
|
57
57
|
|
58
58
|
def punch_all!
|
59
|
-
log.warn 'Punching all ducks!
|
59
|
+
log.warn 'Punching all ducks!'
|
60
60
|
Ducks.list.each &:punch
|
61
61
|
end
|
62
62
|
|
@@ -65,13 +65,10 @@ module DuckPuncher
|
|
65
65
|
end
|
66
66
|
end
|
67
67
|
|
68
|
-
# @description Default logger
|
69
|
-
# @example Silence logging
|
70
|
-
#
|
71
|
-
# `DuckPuncher.log.level = Logger::ERROR`
|
72
|
-
#
|
73
68
|
self.log = Logger.new(STDOUT).tap do |config|
|
74
69
|
config.level = Logger::INFO
|
75
70
|
config.formatter = proc { |*args| "#{args.first}: #{args.last.to_s}\n" }
|
76
71
|
end
|
72
|
+
|
73
|
+
log.level = Logger::ERROR
|
77
74
|
end
|
data/lib/duck_puncher/duck.rb
CHANGED
@@ -18,7 +18,7 @@ module DuckPuncher
|
|
18
18
|
# @option options [Array,Symbol] :only Specifies the methods to extend onto the current object
|
19
19
|
def punch(opts = {})
|
20
20
|
if options[:if] && !options[:if].call
|
21
|
-
DuckPuncher.log.
|
21
|
+
DuckPuncher.log.info %Q(Skipping the punch for #{name}!)
|
22
22
|
return nil
|
23
23
|
end
|
24
24
|
target = opts.delete(:target) || klass
|
data/lib/duck_puncher/ducks.rb
CHANGED
@@ -15,7 +15,7 @@ module DuckPuncher
|
|
15
15
|
|
16
16
|
def [](name)
|
17
17
|
list.find { |duck| duck.name == name.to_sym } ||
|
18
|
-
DuckPuncher.log.
|
18
|
+
DuckPuncher.log.warn(%Q(Couldn't find "#{name}" in my list of Ducks! I know about: #{list.map(&:name).map(&:to_s)}))
|
19
19
|
end
|
20
20
|
|
21
21
|
def load_path_for(duck)
|
@@ -11,7 +11,7 @@ class DuckPuncher::GemInstaller
|
|
11
11
|
begin
|
12
12
|
require spec[:require_with]
|
13
13
|
rescue LoadError => e
|
14
|
-
DuckPuncher.log.
|
14
|
+
DuckPuncher.log.error "Failed to load #{spec[:require_with]} from .duck_puncher/ #{e.inspect}"
|
15
15
|
end
|
16
16
|
end
|
17
17
|
end
|
data/lib/duck_puncher/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: duck_puncher
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.12.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Buckley
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-02-
|
11
|
+
date: 2016-02-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: usable
|