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 +4 -4
- data/README.md +44 -21
- data/bin/console +1 -0
- data/duck_puncher.gemspec +2 -0
- data/lib/duck_puncher/duck.rb +6 -5
- data/lib/duck_puncher/ducks/object.rb +6 -0
- data/lib/duck_puncher/gem_installer.rb +2 -0
- data/lib/duck_puncher/version.rb +1 -1
- data/lib/duck_puncher.rb +3 -1
- metadata +23 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6a8db75a39d70dd7e9d2889e265ee699fb57cc69
|
4
|
+
data.tar.gz: afd816328b5e7e2a525ff440713b9288310e2dad
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
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!
|
56
|
-
DuckPuncher.punch! :Hash, :Object
|
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
|
-
|
68
|
-
|
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
|
-
|
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
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'
|
data/lib/duck_puncher/duck.rb
CHANGED
@@ -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(
|
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
|
-
|
22
|
-
|
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
|
36
|
+
DelegateClass(klass).tap { |k| punch target: k }
|
36
37
|
end
|
37
38
|
|
38
39
|
def classify
|
39
|
-
Class.new(klass).tap
|
40
|
+
Class.new(klass).tap { |k| punch target: k }
|
40
41
|
end
|
41
42
|
end
|
42
43
|
end
|
data/lib/duck_puncher/version.rb
CHANGED
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.
|
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-
|
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.
|
149
|
+
rubygems_version: 2.5.1
|
130
150
|
signing_key:
|
131
151
|
specification_version: 4
|
132
152
|
summary: Duck punches Ruby
|