method_decorators 0.9.3 → 0.9.4

Sign up to get free protection for your applications and to get access to all the features.
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: