data_contract 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
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