oop-interface 0.1.1 → 0.2.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8592f09c32cd65f392c8c40ae971fef707b45562
4
- data.tar.gz: ef2196943e7b68c0f13ae949d7c98d29909c0964
3
+ metadata.gz: 10b7324bf5ce68a960c2884dc98ea5ad2f9cbfec
4
+ data.tar.gz: 0db0e2dd65ade1874f3437ebef2c511f6ff02b31
5
5
  SHA512:
6
- metadata.gz: 7561b0b447f60900970277c9536f30f082e30e8fd81c75a0628dec2089c667a050807345013aff9e0f750c9359d589bcb743bbb1da8bef09dee4ca0d1803610d
7
- data.tar.gz: 2458b6d718c8db7a6edc94a46050e0092092a0479cb04c7bbc433de1edfbfcbfd81420ca979c05e0ffbde2eb0ff31c4058d226e43a73519f34b82790e5f65c21
6
+ metadata.gz: e1205ebef2c4fe39b068a61f760aa07488577e86536d450cd8f09a676f51df943e4dc129e77812757772b7c44459877f8a725ef2909bb88b2da498df169e1b4c
7
+ data.tar.gz: 809530ac060e245706ff52b3266cfd2918955583d20092536768c38975dcdfe8600ea4529192e14eafd644c949f1322ca5e84f6fe6ac68f7006d8787b360558a
@@ -2,5 +2,4 @@ sudo: false
2
2
  language: ruby
3
3
  rvm:
4
4
  - 2.3.3
5
- - ruby-head
6
5
  script: bundle exec rake
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- oop-interface (0.1.0)
4
+ oop-interface (0.2.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # oop-interface - OOP interfaces for Ruby [![Build Status](https://travis-ci.org/andrzejsliwa/oop-interface.svg?branch=master)](https://travis-ci.org/andrzejsliwa/oop-interface)
2
2
 
3
+ The main idea behind of implementation of such gem, was limiting the scope.
4
+ For example when you are implementing Aggregate Root (following Domain Driven Design)
5
+ in ActiveRecord, you would like to expose only public contract methods to ensure that
6
+ Aggregate Root boundaries are not crossed by using directly relations or ActiveRecord methods.
7
+
3
8
  This gem takes inspiration from https://github.com/shuber/interface and
4
9
  borrow some implementation details from it, extend it and modify available api.
5
10
 
@@ -19,7 +24,7 @@ And then execute:
19
24
 
20
25
  Or install it yourself as:
21
26
 
22
- $ gem install interface
27
+ $ gem install oop-interface
23
28
 
24
29
  ## Usage
25
30
 
@@ -49,27 +54,60 @@ Example usage:
49
54
  end
50
55
 
51
56
  > OrderImpl.interfaces
52
- => [Order, Saver]
57
+ => [Order, Saver]
58
+
53
59
  > OrderImpl.unimplemented_methods
54
- => {Order=>[:add_position]}
60
+ => {Order=>[:add_position]}
61
+
55
62
  > saver = OrderImpl.new.as(Saver)
56
- => #<Saver:70247745038560>
63
+ => #<Saver:70247745038560>
64
+
57
65
  > saver.submit
58
66
  NoMethodError: undefined method `submit' for #<Saver:70247745038560>
67
+
59
68
  > saver.save(some: 8)
60
- "save 8"
69
+ => "save 8"
70
+
61
71
  > OrderImpl.new.add_position
62
72
  NotImplementedError: OrderImpl needs to implement 'add_position' for interface Order
73
+
63
74
  > OrderImpl.new.is_a? Saver
64
75
  => true
76
+
65
77
  > OrderImpl.new.is_a? Order
66
78
  => true
67
79
 
68
- The main idea behind of implementation of such gem, was limiting the scope.
69
- For example when you are implementing Aggregate Root (following Domain Driven Design)
70
- in ActiveRecord, you would like to expose only public contract methods to ensure that
71
- Aggregate Root boundaries are not crossed by using directly relations or ActiveRecord methods.
72
-
80
+ # In DDD
81
+
82
+ class OrderImpl < ApplicationRecord
83
+ include Interface
84
+ implements Order
85
+
86
+ has_many :order_lines, ...
87
+
88
+ def submit
89
+ :submitted
90
+ end
91
+ end
92
+
93
+ class OrderRepository
94
+ def load(aggregate_id)
95
+ OrderImpl.find(aggregate_id).as(Order)
96
+ end
97
+ end
98
+
99
+ > order = OrderRepository.new.load(aggregate_id)
100
+ => #<Order:70247745038560>
101
+
102
+ > order.save
103
+ NoMethodError: undefined method `save' for #<Order:70247745038560>
104
+
105
+ > order.order_lines
106
+ NoMethodError: undefined method `order_lines' for #<Order:70247745038560>
107
+
108
+ > order.submit
109
+ => :submittted
110
+
73
111
  ## Development
74
112
 
75
113
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -78,7 +116,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
78
116
 
79
117
  ## Contributing
80
118
 
81
- Bug reports and pull requests are welcome on GitHub at https://github.com/andrzejsliwa/interface.
119
+ Bug reports and pull requests are welcome on GitHub at https://github.com/andrzejsliwa/oop-interface.
82
120
 
83
121
  ## License
84
122
 
@@ -53,34 +53,49 @@ module Interface
53
53
  end
54
54
  end
55
55
 
56
+ def cached_interface_class(interface)
57
+ interface.instance_variable_get("@__cached_class__") || begin
58
+ klass = yield
59
+ interface.instance_variable_set("@__cached_class__", klass)
60
+ klass
61
+ end
62
+ end
63
+
64
+
56
65
  def as(interface)
57
66
  raise UnknownInterface.new(interface) unless self.class.interfaces.include?(interface)
58
- Class.new do
59
- def initialize(target)
60
- @target = target
61
- end
67
+ cached_interface_class(interface) do
68
+ Class.new do
69
+ def initialize(target)
70
+ @target = target
71
+ end
72
+
73
+ interface.instance_methods.select do |method|
74
+ interface.instance_method(method.to_sym).owner == interface
75
+ end.each do |method|
76
+ define_method(method) do |*args, &block|
77
+ @target.public_send(method, *args, &block)
78
+ end
79
+ end
62
80
 
63
- interface.instance_methods.select do |method|
64
- interface.instance_method(method.to_sym).owner == interface
65
- end.each do |method|
66
- define_method(method) do |*args, &block|
67
- @target.public_send(method, *args, &block)
81
+ [:is_a?, :kind_of?, :instance_of?].each do |type_method|
82
+ define_method(type_method) do |target, &block|
83
+ return true if target == interface
84
+ super
85
+ end
68
86
  end
69
- end
70
87
 
71
- [:is_a?, :kind_of?, :instance_of?].each do |type_method|
72
- define_method(type_method) do |target, &block|
73
- return true if target == interface
74
- super
88
+ define_singleton_method :name do
89
+ interface.name
75
90
  end
76
- end
77
91
 
78
- define_method(:inspect) do
79
- "#<#{interface.name}:#{self.object_id}>"
80
- end
92
+ define_singleton_method :inspect do
93
+ name
94
+ end
81
95
 
82
- def to_s
83
- inspect
96
+ define_method(:inspect) do
97
+ "#<#{interface.name}:#{self.object_id}>"
98
+ end
84
99
  end
85
100
  end.new(self)
86
101
  end
@@ -1,3 +1,3 @@
1
1
  module Interface
2
- VERSION = "0.1.1"
2
+ VERSION = "0.2.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: oop-interface
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrzej Sliwa
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2018-01-24 00:00:00.000000000 Z
12
+ date: 2018-03-05 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler