method_decorators 0.9.3 → 0.9.4

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 6785de47236233823f549e66f287ee890f124a26
4
+ data.tar.gz: 4ecf3e013b9f697ae331f0b437141527a8cf9d09
5
+ SHA512:
6
+ metadata.gz: 20d7254686c1318bf47f5c652c2ca58fbfcd00beb215beebaa506997a0c36c4428e3c5074cec2783ba7a344a30aff039395fc24143e8ba1a5bd65148b7526bce
7
+ data.tar.gz: da3881d7736c32a1ecc9412b1fcacef497f7668d0d34a412bb5a758dbc1ab4f3f738b35aaf6858950600e0bcd3a766cc76dc60ee4194bdf0b79abaa22d82f05b
data/.travis.yml CHANGED
@@ -3,10 +3,10 @@ rvm:
3
3
  - 1.8.7
4
4
  - 1.9.2
5
5
  - 1.9.3
6
+ - 2.0.0
6
7
  - jruby-18mode
7
8
  - jruby-19mode
8
- - rbx-18mode
9
- - rbx-19mode
9
+ - rbx-2.1.1
10
10
  - ruby-head
11
11
  - jruby-head
12
- - ree
12
+ - ree
data/README.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  Python's function decorators for Ruby.
4
4
 
5
+ I probably wouldn't use this in production.
6
+
5
7
  ## Installation
6
8
  `gem install method_decorators`
7
9
 
@@ -11,11 +13,13 @@ Python's function decorators for Ruby.
11
13
  Extend MethodDecorators in a class where you want to use them, and then stick `+DecoratorName` before your method declaration to decorate the method.
12
14
 
13
15
  ```ruby
14
- class Math
16
+ require "method_decorators/memoize"
17
+
18
+ class MyMath
15
19
  extend MethodDecorators
16
20
 
17
- +MethodDecorators::Memoized
18
- def fib(n)
21
+ +MethodDecorators::Memoize
22
+ def self.fib(n)
19
23
  if n <= 1
20
24
  1
21
25
  else
@@ -23,6 +27,8 @@ class Math
23
27
  end
24
28
  end
25
29
  end
30
+
31
+ puts MyMath.fib(200)
26
32
  ```
27
33
 
28
34
  You can also decorate with an instance of a decorator, rather than the class. This is useful for configuring specific options for the decorator.
@@ -0,0 +1,84 @@
1
+ require 'method_decorators'
2
+
3
+ module MethodDecorators
4
+ # Example:
5
+ # class MyClass
6
+ # extend MethodDecorators
7
+ #
8
+ # +MethodDecorators::Deprecated
9
+ # def deprecated_method
10
+ # brand_new_method
11
+ # end
12
+ # end
13
+ # When deprecated_method is called, message
14
+ # "MyClass#deprecated_method is deprecated"
15
+ # is output.
16
+ #
17
+ # Another example:
18
+ # class MyClass
19
+ # extend MethodDecorators
20
+ #
21
+ # +MethodDecorators::Deprecated.new('deprecated_method will be removed in the future')
22
+ # def deprecated_method
23
+ # brand_new_method
24
+ # end
25
+ # end
26
+ # Above output given message
27
+ # "deprecated_method will be removed in the future"
28
+ #
29
+ # Custom message example:
30
+ # class MyClass
31
+ # extend MethodDecorators
32
+ #
33
+ # +MethodDecorators::Deprecated.new {|class_name, method_name| "#{class_name}##{method_name} will be removed in the future. Use #{class_name}#brand_new_method instead"}
34
+ # def deprecated_method
35
+ # brand_new_method
36
+ # end
37
+ # end
38
+ # Outputs
39
+ # "MyClass#deprecated_method will be removed in the future. Use MyClass#brand_new_method instead"
40
+ # As you see, you can use class name as the first argument and method name as the second in the block.
41
+ #
42
+ # Formatter example:
43
+ # class Formatter2
44
+ # def call(class_name, method_name)
45
+ # "#{class_name}##{method_name} will be removed after the next version. Use #{class_name}#brand_new_method instead"
46
+ # end
47
+ # end
48
+ # class MyClass
49
+ # extend MethodDecorators
50
+ #
51
+ # formatter1 = ->(class_mane, method_name) {"#{class_name}##{method_name} will be removed in the next version. Use #{class_name}#brand_new_method instead"}
52
+ # +MethodDecorators::Deprecated.new(formatter1)
53
+ # def very_old_method
54
+ # brand_new_method
55
+ # end
56
+ #
57
+ # + MethodDecorators::Deprecated.new(Formatter2.new)
58
+ # def deprecated_method
59
+ # brand_new_method
60
+ # end
61
+ # end
62
+ # Outputs
63
+ # "MyClass#deprecated_method will be removed in the future. Use MyClass#brand_new_method instead"
64
+ # You can give any object which responds to method "call" like Proc.
65
+ class Deprecated < Decorator
66
+ DEFAULT_FORMATTER = lambda {|class_name, method_name| "#{class_name}##{method_name} is deprecated"}
67
+ def initialize(message=nil, &blk)
68
+ @message = message || blk || DEFAULT_FORMATTER
69
+ end
70
+
71
+ def call(orig, this, *args, &blk)
72
+ warn message(this.class, orig.name)
73
+ orig.call(*args, &blk)
74
+ end
75
+
76
+ def message(class_name, method_name)
77
+ if @message.respond_to? :call
78
+ @message.call(class_name, method_name)
79
+ else
80
+ @message.to_s
81
+ end
82
+ end
83
+ end
84
+ end
@@ -2,6 +2,10 @@ require "method_decorators"
2
2
 
3
3
  module MethodDecorators
4
4
  class Memoize < Decorator
5
+ def initialize
6
+ @memo_ivar = "@_memoize_cache#{rand(10**10)}"
7
+ end
8
+
5
9
  def call(orig, this, *args, &blk)
6
10
  return cache(this)[args] if cache(this).has_key?(args)
7
11
  cache(this)[args] = orig.call(*args, &blk)
@@ -9,7 +13,10 @@ module MethodDecorators
9
13
 
10
14
  private
11
15
  def cache(this)
12
- this.instance_variable_get("@_memoize_cache") || this.instance_variable_set("@_memoize_cache", {})
16
+ memo_ivar = @memo_ivar
17
+ this.instance_eval do
18
+ instance_variable_get(memo_ivar) || instance_variable_set(memo_ivar, {})
19
+ end
13
20
  end
14
21
  end
15
22
  end
@@ -1,3 +1,3 @@
1
1
  module MethodDecorators
2
- VERSION = "0.9.3"
2
+ VERSION = "0.9.4"
3
3
  end
@@ -0,0 +1,115 @@
1
+ require 'spec_helper'
2
+ require 'method_decorators/deprecated'
3
+ require 'stringio'
4
+
5
+ describe MethodDecorators::Deprecated do
6
+ let(:method) { double(:method, :call => 'return value of original method', :name => 'deprecated_method') }
7
+
8
+ describe '#call' do
9
+ subject { MethodDecorators::Deprecated.new }
10
+
11
+ it 'calls original method' do
12
+ method.should_receive(:call)
13
+ subject.call(method, nil)
14
+ end
15
+
16
+ it 'warns' do
17
+ subject.should_receive(:warn)
18
+ subject.call(method, nil)
19
+ end
20
+
21
+ context 'when string given on initializing' do
22
+ subject { MethodDecorators::Deprecated.new('custom message') }
23
+
24
+ it 'warns with given string' do
25
+ subject.should_receive(:warn).with('custom message')
26
+ subject.call(method, nil)
27
+ end
28
+ end
29
+
30
+ context 'when block given on initializing' do
31
+ subject { MethodDecorators::Deprecated.new {|klass, method| "#{klass}##{method}"} }
32
+
33
+ it 'warns with message formatted by the block' do
34
+ subject.should_receive(:warn).with('NilClass#deprecated_method')
35
+ subject.call(method, nil)
36
+ end
37
+ end
38
+
39
+ context 'when object which has #call method given on initializing' do
40
+ subject { MethodDecorators::Deprecated.new(lambda { |klass, method| "#{klass}##{method}" }) }
41
+
42
+ it 'warns with message formatted by the object' do
43
+ subject.should_receive(:warn).with('NilClass#deprecated_method')
44
+ subject.call(method, nil)
45
+ end
46
+ end
47
+ end
48
+
49
+ describe 'acceptance' do
50
+ before do
51
+ $stderr = StringIO.new
52
+ subject.deprecated_method
53
+ $stderr.rewind
54
+ end
55
+
56
+ let(:klass) {
57
+ Class.new Base do
58
+ +MethodDecorators::Deprecated
59
+ def deprecated_method
60
+ 'return value of original method'
61
+ end
62
+ end
63
+ }
64
+ subject { klass.new }
65
+
66
+ it 'warns' do
67
+ expect($stderr.read).to eq("#{klass}#deprecated_method is deprecated\n")
68
+ end
69
+
70
+ context 'when string given on initializing' do
71
+ let(:klass) {
72
+ Class.new Base do
73
+ +MethodDecorators::Deprecated.new('custom message')
74
+ def deprecated_method
75
+ 'return value of original method'
76
+ end
77
+ end
78
+ }
79
+
80
+ it 'warns with given string' do
81
+ expect($stderr.read).to eq("custom message\n")
82
+ end
83
+ end
84
+
85
+ context 'when block given on initializing' do
86
+ let(:klass) {
87
+ Class.new Base do
88
+ +MethodDecorators::Deprecated.new {|class_name, method_name| "#{class_name}##{method_name} is deprecated"}
89
+ def deprecated_method
90
+ 'return value of original method'
91
+ end
92
+ end
93
+ }
94
+
95
+ it 'warns with message formatted by the block' do
96
+ expect($stderr.read).to eq("#{klass}#deprecated_method is deprecated\n")
97
+ end
98
+ end
99
+
100
+ context 'when object witch has #call method givn on initializing' do
101
+ let(:klass) {
102
+ Class.new Base do
103
+ +MethodDecorators::Deprecated.new(lambda { |class_name, method_name| "#{class_name}##{method_name} is deprecated" })
104
+ def deprecated_method
105
+ 'return value of original method'
106
+ end
107
+ end
108
+ }
109
+
110
+ it 'warns with message formatted by the object' do
111
+ expect($stderr.read).to eq("#{klass}#deprecated_method is deprecated\n")
112
+ end
113
+ end
114
+ end
115
+ end
@@ -43,6 +43,16 @@ describe MethodDecorators::Memoize do
43
43
  @count += 1
44
44
  rand
45
45
  end
46
+
47
+ +MethodDecorators::Memoize
48
+ def zero
49
+ 0
50
+ end
51
+
52
+ +MethodDecorators::Memoize
53
+ def one
54
+ 1
55
+ end
46
56
  end
47
57
  end
48
58
  subject { klass.new }
@@ -54,6 +64,11 @@ describe MethodDecorators::Memoize do
54
64
  #subject.count.should == 1
55
65
  end
56
66
 
67
+ it "memoizes call to different methods separately" do
68
+ subject.zero.should eql 0
69
+ subject.one.should eql 1
70
+ end
71
+
57
72
  context "with two instances of the decorated class" do
58
73
  let(:o1) { subject }
59
74
  let(:o2) { klass.new }
@@ -13,7 +13,7 @@ describe MethodDecorators::Within do
13
13
 
14
14
  it "does not raise when the method has finished execution before timeout" do
15
15
  method.stub(:call){ sleep 1 }
16
- expect{ subject.call(method, nil) }.to_not raise_error(Timeout::Error)
16
+ expect{ subject.call(method, nil) }.to_not raise_error
17
17
  end
18
18
  end
19
19
 
@@ -36,7 +36,7 @@ describe MethodDecorators::Within do
36
36
 
37
37
  context "with shorter execution period" do
38
38
  it "finishes within the timeout period" do
39
- expect{ subject.do_it(1) }.to_not raise_error(Timeout::Error)
39
+ expect{ subject.do_it(1) }.to_not raise_error
40
40
  end
41
41
  end
42
42
  end
@@ -96,7 +96,7 @@ describe MethodDecorators do
96
96
 
97
97
  it "works" do
98
98
  subject.six.should == '6'
99
- end
99
+ end
100
100
  end
101
101
 
102
102
  describe "that takes args" do
@@ -193,7 +193,7 @@ describe MethodDecorators do
193
193
 
194
194
  it "works" do
195
195
  subject.six.should == '6'
196
- end
196
+ end
197
197
  end
198
198
 
199
199
  describe "that takes args" do
metadata CHANGED
@@ -1,38 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: method_decorators
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.3
5
- prerelease:
4
+ version: 0.9.4
6
5
  platform: ruby
7
6
  authors:
8
7
  - Michael Fairley
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-03-04 00:00:00.000000000 Z
11
+ date: 2014-01-29 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: rake
16
- requirement: &70128902042200 !ruby/object:Gem::Requirement
17
- none: false
15
+ requirement: !ruby/object:Gem::Requirement
18
16
  requirements:
19
- - - ! '>='
17
+ - - '>='
20
18
  - !ruby/object:Gem::Version
21
19
  version: '0'
22
20
  type: :development
23
21
  prerelease: false
24
- version_requirements: *70128902042200
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
25
27
  - !ruby/object:Gem::Dependency
26
28
  name: rspec
27
- requirement: &70128902041760 !ruby/object:Gem::Requirement
28
- none: false
29
+ requirement: !ruby/object:Gem::Requirement
29
30
  requirements:
30
- - - ! '>='
31
+ - - '>='
31
32
  - !ruby/object:Gem::Version
32
33
  version: '0'
33
34
  type: :development
34
35
  prerelease: false
35
- version_requirements: *70128902041760
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
36
41
  description: Python's function decorators for Ruby
37
42
  email:
38
43
  - michaelfairley@gmail.com
@@ -56,12 +61,14 @@ files:
56
61
  - lib/method_decorators/decorators/memoize.rb
57
62
  - lib/method_decorators/decorators/precondition.rb
58
63
  - lib/method_decorators/decorators/retry.rb
64
+ - lib/method_decorators/deprecated.rb
59
65
  - lib/method_decorators/memoize.rb
60
66
  - lib/method_decorators/precondition.rb
61
67
  - lib/method_decorators/retry.rb
62
68
  - lib/method_decorators/version.rb
63
69
  - lib/method_decorators/within.rb
64
70
  - method_decorators.gemspec
71
+ - spec/decorators/deprecated.rb
65
72
  - spec/decorators/memoize_spec.rb
66
73
  - spec/decorators/precondition_spec.rb
67
74
  - spec/decorators/retry_spec.rb
@@ -73,29 +80,29 @@ files:
73
80
  - spec/support/stringify.rb
74
81
  homepage: http://github.com/michaelfairley/method_decorators
75
82
  licenses: []
83
+ metadata: {}
76
84
  post_install_message:
77
85
  rdoc_options: []
78
86
  require_paths:
79
87
  - lib
80
88
  required_ruby_version: !ruby/object:Gem::Requirement
81
- none: false
82
89
  requirements:
83
- - - ! '>='
90
+ - - '>='
84
91
  - !ruby/object:Gem::Version
85
92
  version: '0'
86
93
  required_rubygems_version: !ruby/object:Gem::Requirement
87
- none: false
88
94
  requirements:
89
- - - ! '>='
95
+ - - '>='
90
96
  - !ruby/object:Gem::Version
91
97
  version: '0'
92
98
  requirements: []
93
99
  rubyforge_project:
94
- rubygems_version: 1.8.7
100
+ rubygems_version: 2.0.3
95
101
  signing_key:
96
- specification_version: 3
102
+ specification_version: 4
97
103
  summary: Python's function decorators for Ruby
98
104
  test_files:
105
+ - spec/decorators/deprecated.rb
99
106
  - spec/decorators/memoize_spec.rb
100
107
  - spec/decorators/precondition_spec.rb
101
108
  - spec/decorators/retry_spec.rb
@@ -105,4 +112,3 @@ test_files:
105
112
  - spec/support/add_n.rb
106
113
  - spec/support/reverse.rb
107
114
  - spec/support/stringify.rb
108
- has_rdoc: