data_contract 0.0.2 → 0.0.3

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: 21313bf05ccac5fd51cab90b564671c466fef3e8
4
- data.tar.gz: e47156450c05cd0701743c566409f6b08d67a60a
3
+ metadata.gz: 8578d4e2bac5649c5c7151ba5bd12fe72129ff5b
4
+ data.tar.gz: aacdb343d6a2af0d1afa97c3f4b6d57bdda8f430
5
5
  SHA512:
6
- metadata.gz: 55899798ce639684c28fd30c514de98801084dc42d7ec8ded6142351e7ff3facb54984d990bdc7ca9295714c72c88710929cd2a779fc8a8304128c71c63bf1de
7
- data.tar.gz: 7a7f8e393b9f44c2da1edd7ad206fe7fe282a3e1b897c67a0ecb0f80a1669405e63f50d90e3709ca44a1e5841b9e70702d4fecc6b5ebf3a790df4fcfe3ed67ef
6
+ metadata.gz: cf3068a09d339ae0dada6f14ab9e293304a29ff2c17b22ef294c67f1d05f6e8e301b34b7c041574300f080e501064d55bc0833dff4c9b6b0155de37db80ba447
7
+ data.tar.gz: f459919bc8ed89c4989b207afc692c74d501221490737e770c1e268f37bd6c5905b71e0ca8f0ff1351373e3cdfaa505238dc795afe1ca4e043a0c4d329d91fb9
@@ -0,0 +1,37 @@
1
+ class DataContract < Module
2
+ class Contract
3
+ attr_reader :mod
4
+
5
+ def initialize(mod)
6
+ @mod = mod
7
+ end
8
+
9
+ def setters
10
+ mod.instance_methods(false).select { |m| m.to_s[-1, 1] == '=' }
11
+ end
12
+
13
+ def getters
14
+ mod.instance_methods(false).select { |m| m.to_s[-1, 1] != '=' }
15
+ end
16
+
17
+ def compatible?(other_obj)
18
+ mod.instance_methods(false).each do |m|
19
+ return false unless other_obj.respond_to? m
20
+ end
21
+ return true
22
+ end
23
+
24
+ def shared?(other_obj)
25
+ other_obj.is_a? mod
26
+ end
27
+
28
+ def assignable?(other_obj)
29
+ unless shared? other_obj
30
+ unless compatible? other_obj
31
+ return false
32
+ end
33
+ end
34
+ true
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,4 @@
1
+ class DataContract < Module
2
+ class ContractError < StandardError
3
+ end
4
+ end
@@ -0,0 +1,35 @@
1
+ class DataContract < Module
2
+ class ContractList < Array
3
+ attr_reader :obj
4
+
5
+ def initialize(obj=nil)
6
+ @obj = obj
7
+ end
8
+
9
+ def get(mod)
10
+ contract = find { |contract| contract.mod == mod }
11
+ raise ContractError, "No contract for #{mod.name}" unless contract
12
+ contract
13
+ end
14
+
15
+ def [](mod)
16
+ get mod
17
+ end
18
+
19
+ def assignable(receiver)
20
+ assignable_contracts = self.class.new obj
21
+
22
+ each do |contract|
23
+ if contract.assignable? receiver
24
+ assignable_contracts << contract
25
+ end
26
+ end
27
+
28
+ assignable_contracts
29
+ end
30
+
31
+ def scatter(receiver, contract_module=nil)
32
+ Scatter.! self, receiver, contract_module
33
+ end
34
+ end
35
+ end
@@ -1,16 +1,19 @@
1
1
  class DataContract < Module
2
- def self.[](contract_module)
3
- new contract_module
2
+ def self.[](*contract_modules)
3
+ new contract_modules
4
4
  end
5
5
 
6
- def initialize(contract_module)
7
- mod = contract_module
6
+ def initialize(contract_modules)
7
+ contract_modules.each do |contract_module|
8
+ include contract_module
9
+ end
8
10
 
9
- define_method(:contract_module) do
10
- return contract_module
11
+ mods = contract_modules
12
+ define_method :data_contract_modules do
13
+ return mods
11
14
  end
15
+ private :data_contract_modules
12
16
 
13
- include contract_module
14
- include Implementation
17
+ include DataContractsImpl
15
18
  end
16
19
  end
@@ -0,0 +1,15 @@
1
+ class DataContract < Module
2
+ module DataContractsImpl
3
+ def data_contracts
4
+ return @data_contracts if @data_contracts
5
+
6
+ @data_contracts = ContractList.new self
7
+
8
+ data_contract_modules.each do |contract_module|
9
+ @data_contracts << Contract.new(contract_module)
10
+ end
11
+
12
+ @data_contracts
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,48 @@
1
+ class DataContract < Module
2
+ class Scatter
3
+ include Initializer
4
+
5
+ initializer :list, :source, :receiver, :assignable_contracts, :contract_module
6
+
7
+ def self.!(list, receiver, contract_module)
8
+ assignable_contracts = list.assignable(receiver)
9
+ instance = new list, list.obj, receiver, assignable_contracts, contract_module
10
+ instance.!
11
+ end
12
+
13
+ def !
14
+ if assignable_contracts.empty?
15
+ raise ContractError, "#{receiver.class.name} cannot be assigned from #{source.class.name} without a shared or compatible contract"
16
+ end
17
+
18
+ if contract_module
19
+ @assignable_contracts = specific_contract
20
+ end
21
+
22
+ assignable_contracts.each do |contract|
23
+ copy_data contract
24
+ end
25
+
26
+ receiver
27
+ end
28
+
29
+ def specific_contract
30
+ contract = list[contract_module]
31
+
32
+ unless assignable_contracts.include? contract
33
+ raise ContractError, "#{receiver.class.name} cannot be assigned from #{contract_module.name} without a shared or compatible contract"
34
+ end
35
+
36
+ [contract]
37
+ end
38
+
39
+ def copy_data(contract)
40
+ contract.setters.each do |setter|
41
+ getter = setter[0...-1]
42
+ val = source.send getter
43
+ receiver.send setter, val
44
+ end
45
+ receiver
46
+ end
47
+ end
48
+ end
data/lib/data_contract.rb CHANGED
@@ -1,3 +1,8 @@
1
+ require 'initializer'
2
+
3
+ require 'data_contract/contract'
4
+ require 'data_contract/scatter'
5
+ require 'data_contract/contract_list'
6
+ require 'data_contract/data_contracts_impl'
1
7
  require 'data_contract/data_contract'
2
- require 'data_contract/incompatible_signature_error'
3
- require 'data_contract/implementation'
8
+ require 'data_contract/contract_error'
metadata CHANGED
@@ -1,24 +1,41 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: data_contract
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - The Sans Collective
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-11-24 00:00:00.000000000 Z
12
- dependencies: []
11
+ date: 2013-11-25 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: initializer
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
13
27
  description:
14
28
  email:
15
29
  executables: []
16
30
  extensions: []
17
31
  extra_rdoc_files: []
18
32
  files:
33
+ - lib/data_contract/contract.rb
34
+ - lib/data_contract/contract_error.rb
35
+ - lib/data_contract/contract_list.rb
19
36
  - lib/data_contract/data_contract.rb
20
- - lib/data_contract/implementation.rb
21
- - lib/data_contract/incompatible_signature_error.rb
37
+ - lib/data_contract/data_contracts_impl.rb
38
+ - lib/data_contract/scatter.rb
22
39
  - lib/data_contract.rb
23
40
  homepage: https://github.com/Sans/data-contract
24
41
  licenses: []
@@ -1,27 +0,0 @@
1
- class DataContract < Module
2
- module Implementation
3
- def scatter(target)
4
- raise IncompatibleSignatureError, "#{self.class.name} does not have a shared contract with #{target.class.name}" if !shared_contract? target
5
- setters.each do |setter|
6
- getter = setter[0...-1]
7
- val = send getter
8
- target.send setter, val
9
- end
10
- end
11
-
12
- def setters
13
- contract_module.instance_methods(false).select { |m| m.to_s[-1, 1] == '=' }
14
- end
15
-
16
- def getters
17
- contract_module.instance_methods(false).select { |m| m.to_s[-1, 1] != '=' }
18
- end
19
-
20
- def shared_contract?(other)
21
- contract_module.instance_methods(false).each do |m|
22
- return false unless other.respond_to? m
23
- end
24
- return true
25
- end
26
- end
27
- end
@@ -1,4 +0,0 @@
1
- class DataContract < Module
2
- class IncompatibleSignatureError < StandardError
3
- end
4
- end