easy_decorator 0.1.0 → 0.2.0

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
  SHA256:
3
- metadata.gz: 2a51c2c2a637daadfba8be3453ec7af886c5f484c2ec62a065bcc423f6f4d21c
4
- data.tar.gz: e747a3b3b141dc49e69da1a7efba88e4752e1c06540037cbda78ebb830199f35
3
+ metadata.gz: 9712b4b6313e508e2cff7302f664f5d96fa0bc9e073b82ba6bfb3ec026831e61
4
+ data.tar.gz: 9afdeb38a1b34ab102a571f9514ec8167718aadfddd68f8ffd0993c388227c30
5
5
  SHA512:
6
- metadata.gz: 0c1b39ac4a156d3ad49d04cbcf494394bcd3f7dbd881c98bc445c30bd3eaccc478c264b2e399ec76eab33bd187d786a437a96c7d9b73cffe8921bcc20795e0f1
7
- data.tar.gz: 90904664433a98ff9a275ad5bc1c9beb8ea58cdab973dd3e6da0f80a5b08bf30bb8624752f17e1154ef7f37540941656cff78be4d15ab7fe43d58daab6e89082
6
+ metadata.gz: 3fd37f90cdda492cd0e17c84d33f6c5c47748ace2e4afbc952129efc37909c82001e34f7e0e47d2a015a19d370626ef361bdd8526c406cd3f46cae5e7e8cb267
7
+ data.tar.gz: b0e246be3a9ea5ed7fc80d547aa30aa9ff28a55fdb3d1e11212c6bb5d85f9bd0cfd7e73277e94e0cf11e919cba79e05a78fe03875331d21a6e30338c8e362d62
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/README.md CHANGED
@@ -1,2 +1,114 @@
1
- # easy_decorator
2
- Python-like decorator pattern implemented in Ruby.
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.
@@ -0,0 +1,3 @@
1
+ # Module for decorator helpers and utilities
2
+ module Decorators
3
+ end
@@ -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(decorator, decorated)
11
- @decorated_methods[decorated] = {
12
- decorator: decorator,
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
- send(decorator[:decorator], source_method_name, *args)
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
-
@@ -0,0 +1,3 @@
1
+ module EasyDecorator
2
+ class Error < StandardError; end
3
+ end
@@ -0,0 +1,3 @@
1
+ module EasyDecorator
2
+ VERSION = '0.2.0'
3
+ end
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.1.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