ruby_contracts 0.1.1 → 0.2.1
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.
- data/README.md +8 -0
- data/lib/ruby_contracts/version.rb +1 -1
- data/lib/ruby_contracts.rb +38 -8
- metadata +2 -2
data/README.md
CHANGED
@@ -38,6 +38,14 @@ Run this sample with `ENABLE_ASSERTION=1 bundle exec ruby example.rb`.
|
|
38
38
|
|
39
39
|
Without the environment variable `ENABLE_ASSERTION` you have zero overhead and zero verification.
|
40
40
|
|
41
|
+
## Class inheritance
|
42
|
+
|
43
|
+
When you inherit a class that contains contracts, all contracts must be satified by the subclass.
|
44
|
+
|
45
|
+
If you override a method, you still have to satisfy the existing contracts for this method and you can add some others.
|
46
|
+
|
47
|
+
See the [issue #1](https://github.com/nicoolas25/ruby_contracts/issues/1) for an example.
|
48
|
+
|
41
49
|
## Contributing
|
42
50
|
|
43
51
|
1. Fork it
|
data/lib/ruby_contracts.rb
CHANGED
@@ -3,14 +3,40 @@ require "ruby_contracts/version"
|
|
3
3
|
module Contracts
|
4
4
|
class Error < Exception ; end
|
5
5
|
|
6
|
+
def self.empty_contracts
|
7
|
+
{:before => [], :after => []}
|
8
|
+
end
|
9
|
+
|
6
10
|
module DSL
|
7
11
|
def self.included(base)
|
8
12
|
base.extend Contracts::DSL::ClassMethods
|
13
|
+
base.__contracts_initialize
|
9
14
|
end
|
10
15
|
|
11
16
|
module ClassMethods
|
12
|
-
def
|
13
|
-
|
17
|
+
def inherited(subclass)
|
18
|
+
super
|
19
|
+
subclass.__contracts_initialize
|
20
|
+
end
|
21
|
+
|
22
|
+
def __contracts_initialize
|
23
|
+
@__contracts = Contracts.empty_contracts
|
24
|
+
@__contracts_for = {}
|
25
|
+
end
|
26
|
+
|
27
|
+
def __contracts_for(name, current_contracts=nil)
|
28
|
+
inherited_contracts = ancestors[1..-1].reduce(Contracts.empty_contracts) do |c, klass|
|
29
|
+
ancestor_hash = klass.instance_variable_get('@__contracts_for') || {}
|
30
|
+
c[:before] += ancestor_hash.has_key?(name) ? ancestor_hash[name][:before] : []
|
31
|
+
c[:after] += ancestor_hash.has_key?(name) ? ancestor_hash[name][:after] : []
|
32
|
+
c
|
33
|
+
end
|
34
|
+
current_contracts = @__contracts_for[name] || current_contracts || Contracts.empty_contracts
|
35
|
+
|
36
|
+
contracts = Contracts.empty_contracts
|
37
|
+
contracts[:before] = current_contracts[:before] + inherited_contracts[:before]
|
38
|
+
contracts[:after] = current_contracts[:after] + inherited_contracts[:after]
|
39
|
+
contracts
|
14
40
|
end
|
15
41
|
|
16
42
|
def __contract_failure!(name, message, result, *args)
|
@@ -32,16 +58,20 @@ module Contracts
|
|
32
58
|
end
|
33
59
|
|
34
60
|
def method_added(name)
|
35
|
-
|
36
|
-
|
37
|
-
|
61
|
+
super
|
62
|
+
|
63
|
+
return unless ENV['ENABLE_ASSERTION']
|
64
|
+
return if @__contracts_for.has_key?(name)
|
38
65
|
|
66
|
+
__contracts = @__contracts_for[name] ||= __contracts_for(name, @__contracts)
|
67
|
+
@__contracts = Contracts.empty_contracts
|
68
|
+
|
69
|
+
if !__contracts[:before].empty? || !__contracts[:after].empty?
|
39
70
|
original_method_name = "#{name}__with_contracts"
|
40
71
|
define_method(original_method_name, instance_method(name))
|
41
72
|
|
42
|
-
|
43
73
|
count = 0
|
44
|
-
before_contracts =
|
74
|
+
before_contracts = __contracts[:before].reduce("") do |code, contract|
|
45
75
|
type, *args = contract
|
46
76
|
case type
|
47
77
|
when :type
|
@@ -71,7 +101,7 @@ module Contracts
|
|
71
101
|
end
|
72
102
|
end
|
73
103
|
|
74
|
-
after_contracts =
|
104
|
+
after_contracts = __contracts[:after].reduce("") do |code, contract|
|
75
105
|
type, *args = contract
|
76
106
|
case type
|
77
107
|
when :type
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby_contracts
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2013-06-11 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: Micro DSL to add pre & post condition to methods. It try to bring some
|
15
15
|
design by contract in the Ruby world.
|