duck_puncher 2.12.0 → 2.12.1

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