contracts 0.1.4 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (2) hide show
  1. data/lib/decorators.rb +21 -22
  2. metadata +1 -1
data/lib/decorators.rb CHANGED
@@ -1,14 +1,7 @@
1
1
  module MethodDecorators
2
2
  def self.extended(klass)
3
- klass.class_eval do
4
- @@__decorated_methods ||= {}
5
- def self.__decorated_methods
6
- @@__decorated_methods
7
- end
8
-
9
- def self.__decorated_methods_set(k, v)
10
- @@__decorated_methods[k] = v
11
- end
3
+ class << klass
4
+ attr_accessor :decorated_methods
12
5
  end
13
6
  end
14
7
 
@@ -22,7 +15,6 @@ module MethodDecorators
22
15
  super
23
16
  end
24
17
 
25
- # For Ruby 1.9
26
18
  def singleton_method_added name
27
19
  common_method_added name, true
28
20
  super
@@ -33,33 +25,38 @@ module MethodDecorators
33
25
 
34
26
  decorators = @decorators.dup
35
27
  @decorators = nil
28
+ @decorated_methods ||= {:class_methods => {}, :instance_methods => {}}
29
+
30
+ # attr_accessor on the class variable decorated_methods
31
+ class << self; attr_accessor :decorated_methods; end
36
32
 
37
33
  decorators.each do |klass, args|
38
34
  # a reference to the method gets passed into the contract here. This is good because
39
35
  # we are going to redefine this method with a new name below...so this reference is
40
36
  # now the *only* reference to the old method that exists.
41
- if klass.respond_to? :new
42
- if is_class_method
43
- decorator = klass.new(self, method(name), *args)
44
- else
45
- decorator = klass.new(self, instance_method(name), *args)
46
- end
37
+ # We assume here that the decorator (klass) responds to .new
38
+ if is_class_method
39
+ decorator = klass.new(self, method(name), *args)
40
+ @decorated_methods[:class_methods][name] = decorator
47
41
  else
48
- decorator = klass
42
+ decorator = klass.new(self, instance_method(name), *args)
43
+ @decorated_methods[:instance_methods][name] = decorator
49
44
  end
50
- __decorated_methods_set(name, decorator)
51
45
  end
52
46
 
53
47
  # in place of this method, we are going to define our own method. This method
54
48
  # just calls the decorator passing in all args that were to be passed into the method.
55
49
  # The decorator in turn has a reference to the actual method, so it can call it
56
50
  # on its own, after doing it's decorating of course.
57
- class_eval %{
51
+ class_eval <<-ruby_eval, __FILE__, __LINE__ + 1
58
52
  def #{is_class_method ? "self." : ""}#{name}(*args, &blk)
59
53
  this = self#{is_class_method ? "" : ".class"}
60
- return this.__decorated_methods[#{name.inspect}].call_with(self, *args, &blk)
61
- end
62
- }, __FILE__, __LINE__ + 1
54
+ unless this.respond_to?(:decorated_methods) && !this.decorated_methods.nil?
55
+ raise "Couldn't find decorator for method " + self.class.name + ":#{name}.\nDoes this method look correct to you? If you are using contracts from rspec, rspec wraps classes in it's own class.\nLook at the specs for contracts.ruby as an example of how to write contracts in this case."
56
+ end
57
+ this.decorated_methods[#{is_class_method ? ":class_methods" : ":instance_methods"}][#{name.inspect}].call_with(self, *args, &blk)
58
+ end
59
+ ruby_eval
63
60
  end
64
61
 
65
62
  def decorate(klass, *args)
@@ -92,3 +89,5 @@ class Decorator
92
89
  @method = method
93
90
  end
94
91
  end
92
+
93
+
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: contracts
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.1.4
5
+ version: 0.2.0
6
6
  platform: ruby
7
7
  authors:
8
8
  - Aditya Bhargava