easy_decorator 0.1.0 → 0.2.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/Gemfile +3 -0
- data/README.md +114 -2
- data/lib/decorators/decorators.rb +3 -0
- data/lib/easy_decorator.rb +14 -7
- data/lib/easy_decorator/errors.rb +3 -0
- data/lib/easy_decorator/version.rb +3 -0
- metadata +5 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9712b4b6313e508e2cff7302f664f5d96fa0bc9e073b82ba6bfb3ec026831e61
|
4
|
+
data.tar.gz: 9afdeb38a1b34ab102a571f9514ec8167718aadfddd68f8ffd0993c388227c30
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3fd37f90cdda492cd0e17c84d33f6c5c47748ace2e4afbc952129efc37909c82001e34f7e0e47d2a015a19d370626ef361bdd8526c406cd3f46cae5e7e8cb267
|
7
|
+
data.tar.gz: b0e246be3a9ea5ed7fc80d547aa30aa9ff28a55fdb3d1e11212c6bb5d85f9bd0cfd7e73277e94e0cf11e919cba79e05a78fe03875331d21a6e30338c8e362d62
|
data/Gemfile
ADDED
data/README.md
CHANGED
@@ -1,2 +1,114 @@
|
|
1
|
-
#
|
2
|
-
|
1
|
+
# EasyDecorator
|
2
|
+
|
3
|
+
EasyDecorator is a module that bring's in a Python-like method decorator pattern into Ruby.
|
4
|
+
|
5
|
+
# Table of Contents
|
6
|
+
|
7
|
+
* [Installation](#installation)
|
8
|
+
* [Usage](#usage)
|
9
|
+
* [Include Module](#include-module)
|
10
|
+
* [Define Decorator](#define-decorator)
|
11
|
+
* [Decorating Methods](#decorating-methods)
|
12
|
+
* [Example](#example)
|
13
|
+
* [Contributing](#contributing)
|
14
|
+
|
15
|
+
# Installation
|
16
|
+
### command line
|
17
|
+
`$ gem install easy_decorator`
|
18
|
+
|
19
|
+
### Gemfile
|
20
|
+
```ruby
|
21
|
+
# ./Gemfile
|
22
|
+
|
23
|
+
source 'https://rubygems.org`
|
24
|
+
# ...
|
25
|
+
gem 'easy_decorator', '~> 0.2.0'
|
26
|
+
```
|
27
|
+
# Usage
|
28
|
+
### Include Module
|
29
|
+
```ruby
|
30
|
+
# ./my_class.rb
|
31
|
+
class MyClass
|
32
|
+
include EasyDecorator
|
33
|
+
end
|
34
|
+
```
|
35
|
+
### Define Decorator
|
36
|
+
A decorator should be defined as a method with an inner wrapper. Within the wrapper you can call the passed method via `func.call(*args)`.
|
37
|
+
|
38
|
+
```ruby
|
39
|
+
def my_decorator(func, *args)
|
40
|
+
wrapper do
|
41
|
+
# code here
|
42
|
+
func.call(*args)
|
43
|
+
# code here
|
44
|
+
end
|
45
|
+
end
|
46
|
+
```
|
47
|
+
\* `wrapper` is essentially syntactic sugar for a proc.
|
48
|
+
|
49
|
+
### Decorating Methods
|
50
|
+
```ruby
|
51
|
+
decorate(:my_method, :my_decorator)
|
52
|
+
def my_method(a, b)
|
53
|
+
# code here
|
54
|
+
end
|
55
|
+
```
|
56
|
+
You can apply multiple decorators to a method, which will applies from last to first declared.
|
57
|
+
|
58
|
+
```ruby
|
59
|
+
decorate(:my_method, :outer_decorator)
|
60
|
+
decorate(:my_method, :inner_decorator)
|
61
|
+
def my_method(*args)
|
62
|
+
# ...
|
63
|
+
end
|
64
|
+
|
65
|
+
# is essentially the same as:
|
66
|
+
outer_decorator(inner_decorator(public_method(:my_method))).call(*args)
|
67
|
+
```
|
68
|
+
|
69
|
+
### Example
|
70
|
+
```ruby
|
71
|
+
# ./calculator.rb
|
72
|
+
|
73
|
+
class Calculator
|
74
|
+
# include module
|
75
|
+
include EasyDecorator
|
76
|
+
|
77
|
+
# define decorator
|
78
|
+
def calculate_time(func, *args)
|
79
|
+
wrap do
|
80
|
+
logger.info("Timing #{method_name}...")
|
81
|
+
start_time = Time.now
|
82
|
+
# call inner method
|
83
|
+
result = func.call(*args)
|
84
|
+
end_time = Time.now
|
85
|
+
logger.info("Processing Time: #{end_time - start_time}")
|
86
|
+
|
87
|
+
result
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
# decorate method
|
92
|
+
decorate(:add_numbers, :calculate_time)
|
93
|
+
def add_numbers(a, b)
|
94
|
+
return a + b
|
95
|
+
end
|
96
|
+
end
|
97
|
+
```
|
98
|
+
Result:
|
99
|
+
```
|
100
|
+
$ Calculator.new.add_numbers(1,2)
|
101
|
+
Timing add_numbers...
|
102
|
+
Processing Time: 0.0001572930
|
103
|
+
=> 3
|
104
|
+
```
|
105
|
+
|
106
|
+
# Contributing
|
107
|
+
1. Fork the repo
|
108
|
+
2. Create a your feature branch (`git checkout -b my-feature-branch`)
|
109
|
+
3. Update CHANGELOG.md with a bulleted list of your changes under the `unreleased` heading.
|
110
|
+
4. Include rspec tests for your changes
|
111
|
+
5. Commit your changes to your branch (`git commit -am 'Added my feature'`)
|
112
|
+
6. Push to your remote forked repo (`git push origin my-featuer-branch`)
|
113
|
+
7. Create a new Pull Request
|
114
|
+
Once I am able to review the pull request, I will either either approve and merge, or give feedback on it if I do not merge it. I will do my best to address Pull Requests as time allows.
|
data/lib/easy_decorator.rb
CHANGED
@@ -4,28 +4,35 @@ module EasyDecorator
|
|
4
4
|
def self.included(base_klass)
|
5
5
|
base_klass.extend(ClassMethods)
|
6
6
|
base_klass.instance_variable_set(:@decorated_methods, {})
|
7
|
+
base_klass.define_method :wrapper do |&block|
|
8
|
+
block
|
9
|
+
end
|
7
10
|
end
|
8
11
|
|
9
12
|
module ClassMethods
|
10
|
-
def decorate(
|
11
|
-
@decorated_methods[decorated]
|
12
|
-
|
13
|
-
is_decorated: false
|
14
|
-
}
|
13
|
+
def decorate(decorated, decorator)
|
14
|
+
@decorated_methods[decorated] ||= { method_chain: [], is_decorated: false }
|
15
|
+
@decorated_methods[decorated][:method_chain] << decorator
|
15
16
|
end
|
16
17
|
|
17
18
|
def method_added(method_name)
|
18
19
|
decorator = @decorated_methods[method_name]
|
20
|
+
|
19
21
|
if decorator && !decorator[:is_decorated]
|
20
22
|
decorator[:is_decorated] = true
|
23
|
+
|
21
24
|
source_method_name = "source_#{method_name}".to_sym
|
22
25
|
alias_method source_method_name, method_name
|
26
|
+
decorator[:method_chain] << source_method_name
|
23
27
|
|
24
28
|
define_method method_name do |*args|
|
25
|
-
|
29
|
+
decorator[:method_chain].then { |*funcs, base_func|
|
30
|
+
funcs.reduce(public_method(base_func)) { |acc, func|
|
31
|
+
public_method(func).call(acc, *args)
|
32
|
+
}
|
33
|
+
}.call(*args)
|
26
34
|
end
|
27
35
|
end
|
28
36
|
end
|
29
37
|
end
|
30
38
|
end
|
31
|
-
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: easy_decorator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Josh Crank
|
@@ -45,10 +45,14 @@ extensions: []
|
|
45
45
|
extra_rdoc_files: []
|
46
46
|
files:
|
47
47
|
- ".gitignore"
|
48
|
+
- Gemfile
|
48
49
|
- LICENSE
|
49
50
|
- README.md
|
50
51
|
- easy_decorator.gemspec
|
52
|
+
- lib/decorators/decorators.rb
|
51
53
|
- lib/easy_decorator.rb
|
54
|
+
- lib/easy_decorator/errors.rb
|
55
|
+
- lib/easy_decorator/version.rb
|
52
56
|
homepage: https://github.com/jtcrank/easy_decorator
|
53
57
|
licenses:
|
54
58
|
- MIT
|