duck_puncher 2.7.0 → 2.8.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f48603e05216d29053e2f95e16b169b802bc78e2
4
- data.tar.gz: 044ce7bcd8d7418a24bdc8455c514b642da23913
3
+ metadata.gz: 6a8db75a39d70dd7e9d2889e265ee699fb57cc69
4
+ data.tar.gz: afd816328b5e7e2a525ff440713b9288310e2dad
5
5
  SHA512:
6
- metadata.gz: b79b94c75adda2e450d3799b47ab21564817e732ddbd19f2c05dcec268ed55421f0448bafad72177316afc3cf51e01a4364a1d2ac960b379c8dcafe62ff1bb18
7
- data.tar.gz: c60bc8371e38deeb3b322c3cffeb608ac2df063c9496eabad82f7cc8f3c976c6a0a81770ee79e3e7d0c9fc2b87767307bf9ae516aacab23968dd3bd35dc17d1b
6
+ metadata.gz: 3f69f32294c4ccfe42c934ba0641da5da0e72caa0c205317ee6b090685695593dea1f21003bdad75dd499964d3058a00c87f109b0782ba30e91c9478a9637b65
7
+ data.tar.gz: 6109c6c42f64701e35942f935af09aeaa1081747e6b7a758d5cc32a9655f690b540fcbe0cbdb61068e053bc094054a117705328d5f9d37b63db55a8d193dd311
data/README.md CHANGED
@@ -5,21 +5,41 @@ tough love. You know, lil love punches! :punch: :heart:
5
5
 
6
6
  These are the ducks I love the most:
7
7
 
8
- Array#m => `[].m(:to_s)` => `[].map(&:to_s)`
9
- Array#mm => `[].mm(:sub, /[aeiou]/, '*')` => `[].map { |x| x.sub(/[aeiou]/, '*') }`
10
- Array#get => `[].methods.get('ty?')` => [:empty?]
11
- Hash#dig => `{a: 1, b: {c: 2}}.dig(:b, :c)` => 2 (Part of standard lib in Ruby >= 2.3)
12
- Numeric#to_currency => `25.245.to_currency` => 25.25
13
- Numeric#to_duration => `10_000.to_duration` => '2 h 46 min'
14
- Numeric#to_time_ago => `10_000.to_time_ago` => '2 hours ago'
15
- Numeric#to_rad => `10.15.to_rad` => 0.17715091907742445
16
- String#pluralize => `'hour'.pluralize(2)` => "hours"
17
- String#underscore => `'DuckPuncher::JSONStorage'.underscore` => 'duck_puncher/json_storage'
18
- Object#clone! => `Object.new.clone!` => a deep clone of the object (using Marshal.dump)
19
- Method#to_instruct => `Benchmark.method(:measure).to_instruct` returns the Ruby VM instruction sequence for the method
20
- Method#to_source => `Benchmark.method(:measure).to_source` returns the method definition as a string
21
-
22
- I also provide an experimental punch that tries to download the required gem if it doesn't exist on your computer. The
8
+ ```ruby
9
+ Array#m => `[].m(:to_s)` => `[].map(&:to_s)`
10
+ Array#mm => `[].mm(:sub, /[aeiou]/, '*')` => `[].map { |x| x.sub(/[aeiou]/, '*') }`
11
+ Array#get => `[].methods.get('ty?')` => [:empty?]
12
+ Hash#dig => `{a: 1, b: {c: 2}}.dig(:b, :c)` => 2 (Part of standard lib in Ruby >= 2.3)
13
+ Numeric#to_currency => `25.245.to_currency` => 25.25
14
+ Numeric#to_duration => `10_000.to_duration` => '2 h 46 min'
15
+ Numeric#to_time_ago => `10_000.to_time_ago` => '2 hours ago'
16
+ Numeric#to_rad => `10.15.to_rad` => 0.17715091907742445
17
+ String#pluralize => `'hour'.pluralize(2)` => "hours"
18
+ String#underscore => `'DuckPuncher::JSONStorage'.underscore` => 'duck_puncher/json_storage'
19
+ Object#clone! => `Object.new.clone!` => a deep clone of the object (using Marshal.dump)
20
+ Object#punch => `'duck'.punch` => a copy of 'duck' with the mixed String punches
21
+ Object#track => `'duck'.punch.track` => downloads the [ObjectTracker](https://github.com/ridiculous/object_tracker) gem if it's not available and starts tracking this object
22
+ Method#to_instruct => `Benchmark.method(:measure).to_instruct` returns the Ruby VM instruction sequence for the method
23
+ Method#to_source => `Benchmark.method(:measure).to_source` returns the method definition as a string
24
+ ```
25
+
26
+ ## Tactical punches
27
+
28
+ Sometimes you don't want to punch all the ducks. That's why you can punch only certain methods onto a class:
29
+
30
+ ```ruby
31
+ >> DuckPuncher.punch! :Numeric, only: [:to_currency, :to_duration]
32
+ INFO: Already punched Numeric
33
+ => nil
34
+ >> 100.to_currency '$'
35
+ => "$100.00"
36
+ >> 100.to_duration
37
+ => "1 min"
38
+ >> 100.to_time_ago
39
+ NoMethodError: undefined method `to_time_ago' for 100:Fixnum
40
+ ```
41
+
42
+ There is also an experimental punch that tries to download the required gem if it doesn't exist on your computer. The
23
43
  method is called `require!` and works like this:
24
44
 
25
45
  Downloads and activates a gem for the current and subsequent consoles. For example:
@@ -52,8 +72,9 @@ Ducks need to be _loaded_ before they can be punched! Maybe put this in an initi
52
72
 
53
73
  ```ruby
54
74
  # config/initializers/duck_puncher.rb
55
- DuckPuncher.punch_all! #=> punches all the ducks forever
56
- DuckPuncher.punch! :Hash, :Object #=> only punches the Hash and Object ducks
75
+ DuckPuncher.punch_all! #=> punches all the ducks forever
76
+ DuckPuncher.punch! :Hash, :Object #=> only punches the Hash and Object ducks
77
+ DuckPuncher.punch! :Object, only: :punch #=> only opens a can of whoop ass! Define one method to rule them all
57
78
  ```
58
79
 
59
80
  Create a new class of your favorite duck pre-punched:
@@ -64,14 +85,16 @@ DuckString = DuckPuncher.punch :String #=> give the anonymous duck a name, so t
64
85
  DuckString.new.respond_to? :underscore #=> true
65
86
  ```
66
87
 
67
- That works, but it's pretty verbose and not real pactical to be managing potentially a bunch of custom classes. That's
68
- +why DuckPuncher defines an `Object#punch` method that sets this stuff up for you!
88
+ If you punch `Object` then you can use `punch` on any object to get a new decorated copy of the class with the desired
89
+ functionality mixed in:
69
90
 
70
91
  ```ruby
71
- DuckPuncher.punch! :Object
72
- "yes".punch.to_boolean
92
+ # Assuming you've already done `DuckPuncher.punch! :Object, only: :punch`
93
+ %w[yes no 1].punch.m(:punch).punch.m(:to_boolean) #=> [true, false, true]
73
94
  ```
74
95
 
96
+ Because `DuckPuncher` extends the amazing [Usable](https://github.com/ridiculous/usable) gem, you can configure only the punches you want!
97
+
75
98
  ## Contributing
76
99
 
77
100
  * Fork it
data/bin/console CHANGED
@@ -4,6 +4,7 @@ require 'bundler/setup'
4
4
  require 'pp'
5
5
  require 'duck_puncher'
6
6
  require 'irb'
7
+ require 'byebug'
7
8
  require_relative '../test/fixtures/wut'
8
9
 
9
10
  DuckPuncher.punch_all! if ENV['PUNCH'] != 'no'
data/duck_puncher.gemspec CHANGED
@@ -18,6 +18,8 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ["lib"]
20
20
 
21
+ spec.add_runtime_dependency "usable", "~> 1", "< 2"
22
+
21
23
  spec.add_development_dependency "bundler", "~> 1.3"
22
24
  spec.add_development_dependency "rake", '~> 10.1'
23
25
  spec.add_development_dependency "minitest", '~> 5.0'
@@ -12,14 +12,15 @@ module DuckPuncher
12
12
  "duck_puncher/ducks/#{name.to_s.gsub(/\B([A-Z])/, '_\1').downcase}"
13
13
  end
14
14
 
15
- def punch(target = nil)
15
+ def punch(opts = {})
16
16
  if options[:if] && !options[:if].call
17
17
  DuckPuncher.log.warn %Q(Failed to punch #{name}!)
18
18
  return nil
19
19
  end
20
20
  options[:before].call if options[:before]
21
- (target || klass).send :include, DuckPuncher::Ducks.const_get(name)
22
- options[:after].call if options[:after]
21
+ target = opts.fetch(:target, klass)
22
+ target.extend Usable
23
+ target.usable DuckPuncher::Ducks.const_get(name), opts
23
24
  @punched = true
24
25
  end
25
26
 
@@ -32,11 +33,11 @@ module DuckPuncher
32
33
  end
33
34
 
34
35
  def delegated
35
- DelegateClass(klass).tap &method(:punch)
36
+ DelegateClass(klass).tap { |k| punch target: k }
36
37
  end
37
38
 
38
39
  def classify
39
- Class.new(klass).tap &method(:punch)
40
+ Class.new(klass).tap { |k| punch target: k }
40
41
  end
41
42
  end
42
43
  end
@@ -14,6 +14,12 @@ module DuckPuncher
14
14
  def punch
15
15
  DuckPuncher.delegate_class(self.class.name.to_sym).new(self)
16
16
  end
17
+
18
+ def track
19
+ require! 'object_tracker'
20
+ extend ::ObjectTracker
21
+ track_all!
22
+ end
17
23
  end
18
24
  end
19
25
  end
@@ -1,3 +1,5 @@
1
+ require 'rubygems/dependency_installer'
2
+
1
3
  class DuckPuncher::GemInstaller
2
4
  def self.initialize!
3
5
  spec_data = DuckPuncher::JSONStorage.read('load_paths.json').values
@@ -1,3 +1,3 @@
1
1
  module DuckPuncher
2
- VERSION = '2.7.0'.freeze
2
+ VERSION = '2.8.0'.freeze
3
3
  end
data/lib/duck_puncher.rb CHANGED
@@ -2,6 +2,7 @@ require 'pathname'
2
2
  require 'fileutils'
3
3
  require 'delegate'
4
4
  require 'logger'
5
+ require 'usable'
5
6
  require 'duck_puncher/version'
6
7
 
7
8
  module DuckPuncher
@@ -27,13 +28,14 @@ module DuckPuncher
27
28
  end
28
29
 
29
30
  def punch!(*names)
31
+ options = names.last.is_a?(Hash) ? names.pop : {}
30
32
  names.each do |name|
31
33
  duck = Ducks[name]
32
34
  if duck.punched?
33
35
  log.info %Q(Already punched #{name})
34
36
  else
35
37
  log.warn %Q(Punching #{name} ducky)
36
- unless duck.punch
38
+ unless duck.punch(options)
37
39
  log.error %Q(Failed to punch #{name}!)
38
40
  end
39
41
  end
metadata CHANGED
@@ -1,15 +1,35 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: duck_puncher
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.7.0
4
+ version: 2.8.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-01 00:00:00.000000000 Z
11
+ date: 2016-02-03 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: usable
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1'
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '2'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '1'
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '2'
13
33
  - !ruby/object:Gem::Dependency
14
34
  name: bundler
15
35
  requirement: !ruby/object:Gem::Requirement
@@ -126,7 +146,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
126
146
  version: '0'
127
147
  requirements: []
128
148
  rubyforge_project:
129
- rubygems_version: 2.4.5.1
149
+ rubygems_version: 2.5.1
130
150
  signing_key:
131
151
  specification_version: 4
132
152
  summary: Duck punches Ruby