duck_puncher 2.11.0 → 2.12.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|