duck_puncher 2.12.0 → 2.12.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5df7873691d0800251c6f01efa662ff8ffe5951f
4
- data.tar.gz: 8143c677f0dab3351ed2f19c94b575efc6058682
3
+ metadata.gz: 9e0baa8b465ab3c4158735e6bc53c37f0bbf6883
4
+ data.tar.gz: 34c8cf5c21031da525db6133dbec50e3d4840f26
5
5
  SHA512:
6
- metadata.gz: bb8741aacf58c8f481df8b7976fc263f128d2d27c56deab4b734f08dab0400ed9a8e48b592d0e692f2d25d0f223b07ca64d3a3002ea898d7956eb6d83747be01
7
- data.tar.gz: 43e29a239f7ca340ccc0aa64abd36097d81e3ab6088866eb28bd9b6f6dfd395cf0b8b9e46ae38ca098f52b639a3e6ad9245514607bfb95f8fb9665fab98ab450
6
+ metadata.gz: 202f6cc91ff336089c3761334add4ab4503bd358fef5aa9310fb555545a3b980701ef8db4504b3af75207baa1871956365e1c4dd6cfc1a09c3ad85ee0a8dc136
7
+ data.tar.gz: 8f431ff2ca0ecd65c040842d803edb06012baf39c90d0a806f32c42bed21b57a4677b249659abd5401a0a7d166e74a0e110ac4789a58cf48f7302e16610f0b51
data/README.md CHANGED
@@ -1,9 +1,12 @@
1
1
  # DuckPuncher [![Gem Version](https://badge.fury.io/rb/duck_puncher.svg)](http://badge.fury.io/rb/duck_puncher) [![Build Status](https://travis-ci.org/ridiculous/duck_puncher.svg)](https://travis-ci.org/ridiculous/duck_puncher) [![Code Climate](https://codeclimate.com/github/ridiculous/duck_puncher/badges/gpa.svg)](https://codeclimate.com/github/ridiculous/duck_puncher)
2
2
 
3
- Since Ruby objects walk and talk like ducks, they must therefore _be_ ducks. But ducks don't always behave, and some times they need
4
- tough love! :punch: :heart:
3
+ DuckPuncher provides an interface for administering __duck punches__ (a.k.a "monkey patches"). Punches can be administered in several ways:
5
4
 
6
- These are the ducks I love the most:
5
+ * as an extension
6
+ * as a subclass
7
+ * as a decorator
8
+
9
+ Default extensions:
7
10
 
8
11
  ```ruby
9
12
  Array #m => `[].m(:to_s)` => `[].map(&:to_s)`
@@ -22,35 +25,35 @@ Method #to_instruct => `Benchmark.method(:measure).to_instruct` returns the Ru
22
25
  #to_source => `Benchmark.method(:measure).to_source` returns the method definition as a string
23
26
  ```
24
27
 
25
- ## Tactical punches
28
+ ## Usage
26
29
 
27
- Punch only certain methods onto a duck:
30
+ Punch all registered ducks:
28
31
 
29
32
  ```ruby
30
- >> DuckPuncher.punch! :Numeric, only: [:to_currency, :to_duration]
31
- => nil
32
- >> 100.to_currency '$'
33
- => "$100.00"
34
- >> 100.to_duration
35
- => "1 min"
36
- >> 100.to_time_ago
37
- NoMethodError: undefined method `to_time_ago' for 100:Fixnum
33
+ DuckPuncher.punch_all!
38
34
  ```
39
35
 
40
- ## Install
36
+ Punch individual ducks by name:
41
37
 
42
- gem 'duck_puncher'
38
+ ```ruby
39
+ DuckPuncher.punch! :Hash, :Object
40
+ ```
43
41
 
44
- ## Usage
42
+ One method to rule them all:
45
43
 
46
44
  ```ruby
47
- DuckPuncher.punch_all! # => punches all registered ducks
48
- DuckPuncher.punch! :Hash, :Object # => only punches the Hash and Object ducks
49
- DuckPuncher.punch! :Object, only: :punch # => only opens a can of whoop ass! Define one method to rule them all
45
+ DuckPuncher.punch! :Object, only: :punch
50
46
  ```
51
47
 
52
- The `.punch` method creates and caches a new punched class that inherits from the original. This avoids altering built-in
53
- classes. For example:
48
+ ### Tactical punches
49
+
50
+ Punch only certain methods onto a duck:
51
+
52
+ ```ruby
53
+ DuckPuncher.punch! :Numeric, only: [:to_currency, :to_duration]
54
+ ```
55
+
56
+ The `.punch` method creates and caches a new punched class that __inherits__ from the original:
54
57
 
55
58
  ```ruby
56
59
  >> DuckPuncher.punch :String
@@ -61,7 +64,7 @@ classes. For example:
61
64
  => false
62
65
  ```
63
66
 
64
- If you punch `Object` then you can use `punch` on any object to get a new decorated copy of the class with the desired
67
+ If you punch `Object` then you can use `punch` on any object to get a new __decorated__ copy of the object with the desired
65
68
  functionality mixed in:
66
69
 
67
70
  ```ruby
@@ -72,78 +75,57 @@ functionality mixed in:
72
75
 
73
76
  Because `DuckPuncher` extends the amazing [Usable](https://github.com/ridiculous/usable) gem, you can configure only the punches you want!
74
77
 
75
- ## Registering custom punches
78
+ ### Registering custom punches
76
79
 
77
- DuckPuncher allows you to utilize the `punch` interface to decorate any kind of object with your own punches. Simply call
78
- `.register` with the name of your module.
80
+ DuckPuncher allows you to utilize the `punch` interface to __decorate__ any kind of object with your own punches. Simply
81
+ call `.register` with the name of your module (or an array of names) and any of
82
+ [these options](https://github.com/ridiculous/duck_puncher/blob/master/lib/duck_puncher/duck.rb#L11).
79
83
 
80
- ### Punching your own duck
81
- ```ruby
82
- class User < Struct.new(:name)
83
- end
84
84
 
85
+ ```ruby
86
+ # Define some extensions
85
87
  module Billable
86
- def perform(amt)
88
+ def call(amt)
87
89
  puts "Attempting to bill #{name} for $#{amt}"
88
90
  fail Errno::ENOENT
89
91
  end
90
92
  end
91
93
 
92
94
  module Retryable
93
- def perform_with_retry(*args, retries: 3)
94
- perform *args
95
+ def call_with_retry(*args, retries: 3)
96
+ call *args
95
97
  rescue Errno::ENOENT
96
98
  puts 'retrying'
97
99
  retry if (retries -= 1) > 0
98
100
  end
99
101
  end
100
102
 
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
- ```
103
+ # Register the extensions
104
+ DuckPuncher.register [:Billable, :Retryable]
108
105
 
109
- ### Punching core ducks
110
- ```ruby
111
- # Example punches
112
- module Donald
113
- def tap_tap
114
- p self
115
- self
116
- end
106
+ # Our duck
107
+ class User < Struct.new(:name)
117
108
  end
118
109
 
119
- module Daisy
120
- def quack
121
- "Hi, I'm Daisy"
122
- end
123
- end
110
+ # Add the #punch method to User instances
111
+ DuckPuncher.punch! :Object, only: :punch, target: User
112
+
113
+ # Usage
114
+ user = User.new('Ryan').punch(:Billable).punch(:Retryable)
115
+ user.call_with_retry(19.99)
124
116
  ```
125
117
 
126
- When punching a class, the `:class` option is required when registering:
118
+ When punching at a class level, the `:class` option is required:
127
119
 
128
120
  ```ruby
129
- DuckPuncher.register :Donald, class: 'Array'
130
- DuckPuncher.punch! :Donald
131
- [].tap_tap
121
+ DuckPuncher.register :Billable, class: 'User'
122
+ DuckPuncher.punch! :Billable
132
123
  ```
133
124
 
134
- When punching instances, the `:class` option can be omitted, but the name of the punch is required:
125
+ ## Install
135
126
 
136
- ```ruby
137
- DuckPuncher.punch! :Object, only: :punch
138
- DuckPuncher.register :Donald
139
- DuckPuncher.register :Daisy
140
- ducks = [].punch(:Donald).punch(:Daisy)
141
- ducks.tap_tap
142
- ducks.quack
143
- ```
127
+ gem 'duck_puncher'
144
128
 
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
129
 
148
130
  ## Experimental
149
131
 
@@ -47,7 +47,7 @@ module DuckPuncher
47
47
  options = names.last.is_a?(Hash) ? names.pop : {}
48
48
  names.each do |name|
49
49
  duck = Ducks[name]
50
- log.warn %Q(Punching#{" #{options[:only]} onto" if Array(options[:only]).any?} #{name})
50
+ log.warn %Q(Punching#{" #{options[:only]} onto" if Array(options[:only]).any?} #{options.fetch(:target, name)})
51
51
  unless duck.punch(options)
52
52
  log.error %Q(Failed to punch #{name}!)
53
53
  end
@@ -61,7 +61,9 @@ module DuckPuncher
61
61
  end
62
62
 
63
63
  def register(*args)
64
- Ducks.list << Duck.new(*args)
64
+ Array(args.shift).each do |name|
65
+ Ducks.list << Duck.new(name, *args)
66
+ end
65
67
  end
66
68
  end
67
69
 
@@ -1,3 +1,3 @@
1
1
  module DuckPuncher
2
- VERSION = '2.12.0'.freeze
2
+ VERSION = '2.12.1'.freeze
3
3
  end
@@ -1,17 +1,6 @@
1
1
  require_relative '../test_helper'
2
2
 
3
- module CustomPunch
4
- def tap_tap
5
- p self
6
- self
7
- end
8
- end
9
-
10
3
  class DuckPuncherTest < MiniTest::Test
11
- def teardown
12
- Object.send :remove_const, :CustomPunch
13
- end
14
-
15
4
  def test_register
16
5
  refute_respond_to [], :tap_tap
17
6
  DuckPuncher.register :CustomPunch, class: 'Array'
@@ -20,4 +9,15 @@ class DuckPuncherTest < MiniTest::Test
20
9
  DuckPuncher.punch! :Object, only: :punch
21
10
  assert_respond_to [].punch(:CustomPunch), :tap_tap
22
11
  end
12
+
13
+ def test_register_with_array
14
+ refute_respond_to [], :quack
15
+ refute_respond_to [], :wobble
16
+ DuckPuncher.register [:CustomPunch2, :CustomPunch3], class: 'Array'
17
+ DuckPuncher.punch! :CustomPunch2
18
+ assert_respond_to [], :quack
19
+ refute_respond_to [], :wobble
20
+ DuckPuncher.punch! :CustomPunch3
21
+ assert_respond_to [], :wobble
22
+ end
23
23
  end
@@ -4,3 +4,20 @@ require 'minitest/reporters'
4
4
  require 'duck_puncher'
5
5
 
6
6
  Minitest::Reporters.use!
7
+
8
+ module CustomPunch
9
+ def tap_tap
10
+ p self
11
+ self
12
+ end
13
+ end
14
+
15
+ module CustomPunch2
16
+ def quack
17
+ end
18
+ end
19
+
20
+ module CustomPunch3
21
+ def wobble
22
+ end
23
+ end
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.12.0
4
+ version: 2.12.1
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-27 00:00:00.000000000 Z
11
+ date: 2016-03-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: usable