interfacable 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +23 -12
- data/lib/interfacable.rb +14 -25
- data/lib/interfacable/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8de2fb0e6c98975d368f5c465b1a45c0fb30aaef9355a2ec981c6afdc8a59766
|
4
|
+
data.tar.gz: d9b3e6a76c2384ba3a25775bcf8e42aa129d46676f84251f5eb81eede7e14fb9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: db99b9ce149cdc158de87fc11195140ac39b9fbb4cccb48f7f5975c173d9fcb879a61e056e85f4a67bd813b69c997ebe16f1ae4e535b02749219b8b5ab3ade53
|
7
|
+
data.tar.gz: aea709d864dd1a0c4939b67b4c662b5283669c4e34bd22cd45e68a7b51b1bbbf7b2d4feac3997488c53eff7cf16e1283947158b458ae71d428b83f856d939c93
|
data/README.md
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
# Interfacable [![Build Status](https://travis-ci.org/artemave/interfacable.svg?branch=master)](https://travis-ci.org/artemave/interfacable)
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
This gem allows you to impose interfaces on classes and automatically checks that those constraints are met.
|
3
|
+
Impose interfaces on classes and let this gem automatically check that the interface constraints are met.
|
6
4
|
|
7
5
|
## Installation
|
8
6
|
|
@@ -16,15 +14,15 @@ And then execute:
|
|
16
14
|
|
17
15
|
$ bundle install
|
18
16
|
|
19
|
-
Or install it yourself as:
|
20
|
-
|
21
|
-
$ gem install interfacable
|
22
|
-
|
23
17
|
## Usage
|
24
18
|
|
25
19
|
In this example:
|
26
20
|
|
27
21
|
```ruby
|
22
|
+
class Class
|
23
|
+
include Interfacable
|
24
|
+
end
|
25
|
+
|
28
26
|
module Carrier
|
29
27
|
def call(number); end
|
30
28
|
|
@@ -32,19 +30,19 @@ module Carrier
|
|
32
30
|
end
|
33
31
|
|
34
32
|
class Giffgaff
|
35
|
-
include Interfacable
|
36
|
-
|
37
33
|
implements Carrier
|
38
34
|
end
|
39
35
|
```
|
40
36
|
|
41
|
-
An attempt to
|
37
|
+
An attempt to _load_ this code will result in the following error:
|
42
38
|
|
43
39
|
Giffgaff must implement: (Interfacable::Error)
|
44
40
|
- Carrier#text
|
45
41
|
- Carrier#call
|
46
42
|
|
47
|
-
It will keep failing until `Giffgaff` defines those methods.
|
43
|
+
It will keep failing until `Giffgaff` defines those methods.
|
44
|
+
|
45
|
+
Correctly. E.g.:
|
48
46
|
|
49
47
|
```ruby
|
50
48
|
class Giffgaff
|
@@ -54,9 +52,22 @@ class Giffgaff
|
|
54
52
|
end
|
55
53
|
```
|
56
54
|
|
57
|
-
|
55
|
+
Will fail because of method signature mismatch:
|
58
56
|
|
59
57
|
Giffgaff must implement correctly: (Interfacable::Error)
|
60
58
|
- Carrier#text:
|
61
59
|
- expected arguments: (req, req)
|
62
60
|
- actual arguments: (req)
|
61
|
+
|
62
|
+
### Rails
|
63
|
+
|
64
|
+
For extra piece of mind, we can noop interface checking in production:
|
65
|
+
|
66
|
+
```ruby
|
67
|
+
# config/initializers/interfacable.rb
|
68
|
+
class Class
|
69
|
+
include Interfacable
|
70
|
+
|
71
|
+
def implements(*args); end if Rails.env.production?
|
72
|
+
end
|
73
|
+
```
|
data/lib/interfacable.rb
CHANGED
@@ -10,34 +10,23 @@ module Interfacable
|
|
10
10
|
class Error < Exception; end
|
11
11
|
# rubocop:enable Lint/InheritException
|
12
12
|
|
13
|
-
def
|
14
|
-
|
15
|
-
end
|
16
|
-
|
17
|
-
def self.included(base)
|
18
|
-
base.extend ClassMethods
|
19
|
-
end
|
13
|
+
def implements(*interfaces)
|
14
|
+
(@interfaces ||= []).push(*interfaces)
|
20
15
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
# rubocop:enable Naming/MemoizedInstanceVariableName
|
31
|
-
if self == t.self
|
32
|
-
unless (errors = ImplementationCheck.new(self).perform(@interfaces)).empty?
|
33
|
-
error_message = ErrorFormatter.new(self).format_errors(errors)
|
34
|
-
raise(Error, error_message)
|
35
|
-
end
|
36
|
-
|
37
|
-
t.disable
|
16
|
+
# rubocop:disable Naming/MemoizedInstanceVariableName
|
17
|
+
@interfacable_trace ||= TracePoint.trace(:end) do |t|
|
18
|
+
# simplecov does not see inside this block
|
19
|
+
# :nocov:
|
20
|
+
# rubocop:enable Naming/MemoizedInstanceVariableName
|
21
|
+
if self == t.self
|
22
|
+
unless (errors = ImplementationCheck.new(self).perform(@interfaces)).empty?
|
23
|
+
error_message = ErrorFormatter.new(self).format_errors(errors)
|
24
|
+
raise(Error, error_message)
|
38
25
|
end
|
39
|
-
|
26
|
+
|
27
|
+
t.disable
|
40
28
|
end
|
29
|
+
# :nocov:
|
41
30
|
end
|
42
31
|
end
|
43
32
|
end
|
data/lib/interfacable/version.rb
CHANGED