decoratable 0.0.1 → 0.0.2
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/.travis.yml +4 -3
- data/README.rdoc +100 -0
- data/decoratable.gemspec +3 -1
- data/lib/decoratable/deprecatable.rb +12 -0
- data/lib/decoratable.rb +6 -0
- data/test/decoratable/deprecatable_test.rb +40 -0
- data/test/decoratable_test.rb +1 -3
- metadata +35 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ec20dff74a6642c85271dcb977529bcd33ca8174
|
4
|
+
data.tar.gz: 9ff3c561a008fff52d078a61ec2ab68630756580
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c940d91c425fd100b43d850ae9e78522ae385a5dc9a52bd321b73c82b8f2f8411e6f4a53597699c657d4a5647d359cf15e30c70abc7198161494f74eeee5d65a
|
7
|
+
data.tar.gz: 6ef5795b503abba017d278c6bfdcd52c3d04d1929d99a7901829d0f09b14ac10e6db41c87188de9cf4d24d41c19e1b01e6ae3d123986948478bc5445596acba2
|
data/.travis.yml
CHANGED
data/README.rdoc
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
= Decoratable
|
2
|
+
|
3
|
+
Provides an easy way to define decorations that add common behaviour to your methods.
|
4
|
+
|
5
|
+
== Installation
|
6
|
+
|
7
|
+
gem install decoratable
|
8
|
+
|
9
|
+
== Requirements
|
10
|
+
|
11
|
+
Decoratable does its magic via Module#prepend, which means:
|
12
|
+
|
13
|
+
* MRI (1.9.3 and up) OR
|
14
|
+
* JRuby 9000
|
15
|
+
|
16
|
+
== Usage
|
17
|
+
|
18
|
+
require "decoratable"
|
19
|
+
|
20
|
+
module Retryable
|
21
|
+
# All methods defined in this module can decorate methods
|
22
|
+
extend Decoratable
|
23
|
+
|
24
|
+
def retryable(tries = 1, options = { on: [RuntimeError] })
|
25
|
+
attempt = 0
|
26
|
+
# To invoke the original method, simply use `yield`
|
27
|
+
yield
|
28
|
+
rescue *options[:on]
|
29
|
+
attempt += 1
|
30
|
+
attempt > tries ? raise : retry
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
module Pryable
|
35
|
+
extend Decoratable
|
36
|
+
|
37
|
+
def pryable
|
38
|
+
yield
|
39
|
+
rescue => e
|
40
|
+
require "pry"
|
41
|
+
binding.pry
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
module Measurable
|
46
|
+
extend Decoratable
|
47
|
+
|
48
|
+
def measurable(logger = Logger.new(STDOUT))
|
49
|
+
start = Time.now
|
50
|
+
yield
|
51
|
+
ensure
|
52
|
+
# The decoration has access to the original method
|
53
|
+
# args and any block passed in the original method call are also available
|
54
|
+
# via __args__ and __block__ respectively
|
55
|
+
original_method = __decorated_method__
|
56
|
+
|
57
|
+
method_location, line = original_method.source_location
|
58
|
+
marker = "#{original_method.owner}##{original_method.name}[#{method_location}:#{line}]"
|
59
|
+
duration = (Time.now - start).round(2)
|
60
|
+
|
61
|
+
logger.info "#{marker} took #{duration}s to run."
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
class Client
|
66
|
+
extend Measurable
|
67
|
+
extend Pryable
|
68
|
+
extend Retryable
|
69
|
+
|
70
|
+
# This method will automatically retry on TimeoutErrors, up to 3 times
|
71
|
+
retryable(tries = 3, on: [TimeoutError])
|
72
|
+
def get
|
73
|
+
…
|
74
|
+
end
|
75
|
+
|
76
|
+
# If an error is raised in this method, we'll automatically get a pry session
|
77
|
+
# to help us debug it
|
78
|
+
pryable
|
79
|
+
def post
|
80
|
+
…
|
81
|
+
end
|
82
|
+
|
83
|
+
# Log the time this method takes to run
|
84
|
+
measurable
|
85
|
+
def delete
|
86
|
+
…
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
Decoratable provides a handful of decorations as part of the gem:
|
91
|
+
|
92
|
+
* require "decoratable/countable": keep a count each time a method gets called
|
93
|
+
* require "decoratable/debuggable": open a Ruby debug console (i.e. require "debug") if an error is raised
|
94
|
+
* require "decoratable/deprecatable": log a warning whenever a deprecated method gets called; logs the caller's location
|
95
|
+
* require "decoratable/hintable": add type hinting to your method arguments
|
96
|
+
* require "decoratable/memoizable": automatically memoize the return value of a method
|
97
|
+
* require "decoratable/pryable": open a Pry debug console (i.e. binding.pry) if an error is raised
|
98
|
+
* require "decoratable/retryable": automatically retry a number of times when a specified exception is raised
|
99
|
+
|
100
|
+
More to be added as time goes on.
|
data/decoratable.gemspec
CHANGED
@@ -3,7 +3,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
3
3
|
|
4
4
|
Gem::Specification.new do |spec|
|
5
5
|
spec.name = "decoratable"
|
6
|
-
spec.version = "0.0.
|
6
|
+
spec.version = "0.0.2"
|
7
7
|
spec.authors = ["ecin"]
|
8
8
|
spec.email = ["ecin@copypastel.com"]
|
9
9
|
spec.description = "Decorate your methods."
|
@@ -16,5 +16,7 @@ Gem::Specification.new do |spec|
|
|
16
16
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
17
17
|
spec.require_paths = ["lib"]
|
18
18
|
|
19
|
+
spec.add_development_dependency "minitest"
|
19
20
|
spec.add_development_dependency "pry"
|
21
|
+
spec.add_development_dependency "rake", ">= 10.0.0"
|
20
22
|
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require "decoratable"
|
2
|
+
|
3
|
+
require "logger"
|
4
|
+
|
5
|
+
module Deprecatable
|
6
|
+
extend Decoratable
|
7
|
+
|
8
|
+
def deprecatable(logger = Logger.new(STDOUT))
|
9
|
+
logger.warn("#{__decorated_method__.name} is deprecated. Called from: #{__original_caller__[0]}")
|
10
|
+
yield
|
11
|
+
end
|
12
|
+
end
|
data/lib/decoratable.rb
CHANGED
@@ -91,6 +91,10 @@ module Decoratable
|
|
91
91
|
alias_method "method_added_without_#{decoration_name}", :method_added
|
92
92
|
end
|
93
93
|
|
94
|
+
unless method_defined?(:__original_caller__)
|
95
|
+
define_method(:__original_caller__) { @__original_caller__ }
|
96
|
+
end
|
97
|
+
|
94
98
|
unless method_defined?(:__decorated_method__)
|
95
99
|
define_method(:__decorated_method__) { @__decorated_method__ }
|
96
100
|
end
|
@@ -126,6 +130,7 @@ module Decoratable
|
|
126
130
|
@__decorated_method__ = original_method
|
127
131
|
@__args__ = args
|
128
132
|
@__block__ = block
|
133
|
+
@__original_caller__ ||= caller
|
129
134
|
|
130
135
|
decoration_method.bind(self).call(*decorator_args) do
|
131
136
|
super(*args, &block)
|
@@ -134,6 +139,7 @@ module Decoratable
|
|
134
139
|
@__decorated_method__ = nil
|
135
140
|
@__args__ = nil
|
136
141
|
@__block__ = nil
|
142
|
+
@__original_caller__ = nil
|
137
143
|
end
|
138
144
|
end
|
139
145
|
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
require "decoratable/deprecatable"
|
4
|
+
require "decoratable/retryable"
|
5
|
+
require "decoratable/memoizable"
|
6
|
+
|
7
|
+
describe Deprecatable do
|
8
|
+
extend Memoizable
|
9
|
+
|
10
|
+
before do
|
11
|
+
# Need to assign to a local variable so it's accessible from
|
12
|
+
# the following class definition scope.
|
13
|
+
logger = mock_logger
|
14
|
+
|
15
|
+
klass = Class.new do
|
16
|
+
extend Deprecatable
|
17
|
+
extend Retryable
|
18
|
+
|
19
|
+
deprecatable(logger)
|
20
|
+
def old_method; end
|
21
|
+
end
|
22
|
+
|
23
|
+
@object = klass.new
|
24
|
+
end
|
25
|
+
|
26
|
+
it "prints a warning when a method is called" do
|
27
|
+
# If the `@object.old_method` line moves around, we'll have to modify the line arithmetic for the
|
28
|
+
# expected regex.
|
29
|
+
mock_logger.expect(:warn, nil, [/old_method is deprecated\. Called from: #{__FILE__}:#{__LINE__ + 2}/])
|
30
|
+
|
31
|
+
@object.old_method
|
32
|
+
mock_logger.verify
|
33
|
+
end
|
34
|
+
|
35
|
+
# Reusing library code in a test? Amazing!
|
36
|
+
memoizable
|
37
|
+
def mock_logger
|
38
|
+
Minitest::Mock.new
|
39
|
+
end
|
40
|
+
end
|
data/test/decoratable_test.rb
CHANGED
@@ -142,9 +142,7 @@ describe Decoratable do
|
|
142
142
|
|
143
143
|
def mock_logger
|
144
144
|
logger = Minitest::Mock.new
|
145
|
-
logger.expect(:info, nil
|
146
|
-
message =~ /took \d+\.\d+s to run/
|
147
|
-
end
|
145
|
+
logger.expect(:info, nil, [/took \d+\.\d+s to run/])
|
148
146
|
logger
|
149
147
|
end
|
150
148
|
end
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: decoratable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ecin
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-11-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: minitest
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: pry
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -24,6 +38,20 @@ dependencies:
|
|
24
38
|
- - ">="
|
25
39
|
- !ruby/object:Gem::Version
|
26
40
|
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 10.0.0
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 10.0.0
|
27
55
|
description: Decorate your methods.
|
28
56
|
email:
|
29
57
|
- ecin@copypastel.com
|
@@ -33,16 +61,19 @@ extra_rdoc_files: []
|
|
33
61
|
files:
|
34
62
|
- ".travis.yml"
|
35
63
|
- Gemfile
|
64
|
+
- README.rdoc
|
36
65
|
- Rakefile
|
37
66
|
- decoratable.gemspec
|
38
67
|
- lib/decoratable.rb
|
39
68
|
- lib/decoratable/countable.rb
|
40
69
|
- lib/decoratable/debuggable.rb
|
70
|
+
- lib/decoratable/deprecatable.rb
|
41
71
|
- lib/decoratable/hintable.rb
|
42
72
|
- lib/decoratable/memoizable.rb
|
43
73
|
- lib/decoratable/pryable.rb
|
44
74
|
- lib/decoratable/retryable.rb
|
45
75
|
- test/decoratable/countable_test.rb
|
76
|
+
- test/decoratable/deprecatable_test.rb
|
46
77
|
- test/decoratable/hintable_test.rb
|
47
78
|
- test/decoratable/memoizable_test.rb
|
48
79
|
- test/decoratable/pryable_test.rb
|
@@ -69,16 +100,16 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
69
100
|
version: '0'
|
70
101
|
requirements: []
|
71
102
|
rubyforge_project:
|
72
|
-
rubygems_version: 2.
|
103
|
+
rubygems_version: 2.5.1
|
73
104
|
signing_key:
|
74
105
|
specification_version: 4
|
75
106
|
summary: Easily define decorations for your methods. Put a bow on it.
|
76
107
|
test_files:
|
77
108
|
- test/decoratable/countable_test.rb
|
109
|
+
- test/decoratable/deprecatable_test.rb
|
78
110
|
- test/decoratable/hintable_test.rb
|
79
111
|
- test/decoratable/memoizable_test.rb
|
80
112
|
- test/decoratable/pryable_test.rb
|
81
113
|
- test/decoratable/retryable_test.rb
|
82
114
|
- test/decoratable_test.rb
|
83
115
|
- test/test_helper.rb
|
84
|
-
has_rdoc:
|