wrapper_based 0.5.0 → 1.0.0

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: 9411d5ab7b4f35eb11de0d1c80a8f94a452001d4
4
- data.tar.gz: afef2d54a25ab9110a9403f5be0ec19a2dbda211
3
+ metadata.gz: 8250109a727470549a4a5ad7eeeb2b83deb22ded
4
+ data.tar.gz: aad939be5697e39f97d8adfcb2978ef723702516
5
5
  SHA512:
6
- metadata.gz: 1a91041080d96a68f4c25ad70ef0dd6ba21d55befdfef62d845b3d42cb6bc21ca89453ae48f02a1c57b98c71204d80c75d0665a1d6bf70e6dd2d40a6d4b07f3a
7
- data.tar.gz: 3d6421e710976af3cb2b13b9a3dd354c114ef7d2dfbf389c83291958931e405b6fb73e383baf4b6d6bd3999397765a73b218fb4196be86f37acb7e77ef083856
6
+ metadata.gz: 71ec411aaa5a9ebaeab67749f5adcc66e1b2921cbb58e22ce3a49385e4d8173a8502f3582c6187af6a3829cfda489ff81eb734ce5d55e6b559409d287a80d72e
7
+ data.tar.gz: 183610fab65d79dee5b6c08f8f1bc849718fb1241478d9937bff0fe283d3ebd429fdbb1d493122bd2c52109703d6c1dd6152cb301a33b2f602be07b748beb8eb
data/.travis.yml CHANGED
@@ -1,5 +1,8 @@
1
1
  sudo: false
2
2
  language: ruby
3
3
  rvm:
4
+ - 2.1.0
5
+ - 2.2.0
6
+ - 2.3.0
4
7
  - 2.4.0
5
8
  before_install: gem install bundler -v 1.15.0
data/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  # WrapperBased
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/wrapper_based.svg)](https://badge.fury.io/rb/wrapper_based)
4
+ [![Build Status](https://travis-ci.org/RichOrElse/wrapper-based.svg?branch=master)](https://travis-ci.org/RichOrElse/wrapper-based)
4
5
 
5
6
  Wrapper Based DCI implementation in Ruby.
6
7
 
@@ -20,23 +21,21 @@ Or install it yourself as:
20
21
 
21
22
  $ gem install wrapper_based
22
23
 
23
- ## Usage
24
+ Require DCI in your gems or save in your rails app as app/config/dci.rb:
25
+
24
26
 
25
27
  ```ruby
26
- require_relative 'dijkstra/data'
27
- # See https://github.com/RichOrElse/wrapper-based/blob/master/test/dijkstra_test.rb
28
+ require 'wrapper_based/dci'
29
+ ```
28
30
 
29
- # Behaviors
31
+ ## Usage
30
32
 
31
- module Map
32
- def distance_between(a, b)
33
- @distances[Edge.new(a, b)]
34
- end
33
+ [Dijkstra data](https://github.com/RichOrElse/wrapper-based/blob/master/examples/dijkstra/data.rb) |
34
+ [Dijkstra test](https://github.com/RichOrElse/wrapper-based/blob/master/test/dijkstra_test.rb) |
35
+ Djikstra example:
35
36
 
36
- def distance_of(path)
37
- GetDistance[within: self].of(path)
38
- end
39
- end
37
+ ```ruby
38
+ require_relative 'dijkstra/data'
40
39
 
41
40
  module CurrentIntersection
42
41
  def neighbors(manhattan:)
@@ -53,9 +52,15 @@ module DestinationNode
53
52
  end
54
53
  end
55
54
 
56
- # Contexts
55
+ module Map
56
+ def distance_between(a, b)
57
+ @distances[Edge.new(a, b)]
58
+ end
57
59
 
58
- DCI = WrapperBased::DCI.new unless defined? DCI
60
+ def distance_of(path)
61
+ GetDistance[within: self].of(path)
62
+ end
63
+ end
59
64
 
60
65
  class GetDistance < DCI::Context(:within)
61
66
  within.as Map
@@ -1,7 +1,7 @@
1
1
  # Source: http://fulloo.info/Examples/RubyExamples/Dijkstra/DijkstraListing.html
2
2
 
3
3
  def infinity
4
- 2**(0.size * 8 -2) -1
4
+ 2**(0.size * 8 - 2) - 1
5
5
  end
6
6
 
7
7
  #
data/examples/dijkstra.rb CHANGED
@@ -1,18 +1,6 @@
1
1
  require_relative 'dijkstra/data'
2
2
  # See https://github.com/RichOrElse/wrapper-based/blob/master/test/dijkstra_test.rb
3
3
 
4
- # Behaviors
5
-
6
- module Map
7
- def distance_between(a, b)
8
- @distances[Edge.new(a, b)]
9
- end
10
-
11
- def distance_of(path)
12
- GetDistance[within: self].of(path)
13
- end
14
- end
15
-
16
4
  module CurrentIntersection
17
5
  def neighbors(manhattan:)
18
6
  east_neighbor = manhattan.east_neighbor_of(self)
@@ -28,9 +16,15 @@ module DestinationNode
28
16
  end
29
17
  end
30
18
 
31
- # Contexts
19
+ module Map
20
+ def distance_between(a, b)
21
+ @distances[Edge.new(a, b)]
22
+ end
32
23
 
33
- DCI = WrapperBased::DCI.new unless defined? DCI
24
+ def distance_of(path)
25
+ GetDistance[within: self].of(path)
26
+ end
27
+ end
34
28
 
35
29
  class GetDistance < DCI::Context(:within)
36
30
  within.as Map
@@ -1,41 +1,48 @@
1
1
  LogTransaction = Struct.new(:transaction_type, :amount, :account_number)
2
- Account = Struct.new(:number, :balance)
3
- NotEnoughFunds = Class.new(StandardError)
4
2
 
5
- module SourceAccount
6
- def decrease_balance_by(amount)
7
- fail NotEnoughFunds, "Balance is below amount.", caller if balance < amount
8
- self.balance -= amount
3
+ module Funds
4
+ Insufficient = Class.new(StandardError)
5
+
6
+ module SourceAccount
7
+ def decrease_balance_by(amount)
8
+ fail Funds::Insufficient, "Balance is below amount.", caller if balance < amount
9
+ self.balance -= amount
10
+ end
9
11
  end
10
- end
11
12
 
12
- module DestinationAccount
13
- def increase_balance_by(amount)
14
- self.balance += amount
13
+ module DestinationAccount
14
+ def increase_balance_by(amount)
15
+ self.balance += amount
16
+ end
15
17
  end
16
- end
17
18
 
18
- DCI = WrapperBased::DCI.new unless defined? DCI
19
+ class TransferMoney < DCI::Context(:from, :to)
20
+ from.as SourceAccount
21
+ to.as DestinationAccount
19
22
 
20
- class TransferMoney < DCI::Context(:from, :to)
21
- from.as SourceAccount
22
- to.as DestinationAccount
23
+ def withdraw(amount)
24
+ from.decrease_balance_by(amount)
25
+ LogTransaction["Withdraw", amount, from.number]
26
+ end
23
27
 
24
- def withdraw(amount)
25
- from.decrease_balance_by(amount)
26
- LogTransaction["Withdraw", amount, from.number]
27
- end
28
+ def deposit(amount)
29
+ to.increase_balance_by(amount)
30
+ LogTransaction["Deposit", amount, to.number]
31
+ end
32
+
33
+ def accounts
34
+ [@from, @to]
35
+ end
28
36
 
29
- def deposit(amount)
30
- to.increase_balance_by(amount)
31
- LogTransaction["Deposit", amount, to.number]
37
+ def call(amount:)
38
+ transaction_logs = [withdraw(amount), deposit(amount)]
39
+ [:success, { logs: transaction_logs }, accounts]
40
+ rescue Funds::Insufficient => error
41
+ [:failure, { message: error.message }, accounts]
42
+ end
32
43
  end
33
44
 
34
- def call(amount:)
35
- accounts = [@from, @to]
36
- transaction_logs = [withdraw(amount), deposit(amount)]
37
- [:success, { logs: transaction_logs }, accounts]
38
- rescue NotEnoughFunds => error
39
- [:failure, { message: error.message }, accounts]
45
+ def self.transfer(**where)
46
+ TransferMoney[**where]
40
47
  end
41
48
  end
data/examples/toy_shop.rb CHANGED
@@ -1,5 +1,3 @@
1
- require_relative '../lib/wrapper_based'
2
-
3
1
  # Data
4
2
 
5
3
  Purchase = Struct.new(:toy, :buyer)
@@ -20,7 +18,6 @@ module Recipient
20
18
  end
21
19
 
22
20
  # Contexts
23
- DCI = WrapperBased::DCI.new unless defined? DCI
24
21
 
25
22
  class PurchaseToy < DCI::Context(:purchaser)
26
23
  purchaser.as Buyer
@@ -0,0 +1,20 @@
1
+ module WrapperBased
2
+ class Context::Builder < Module
3
+ def initialize(wrapper_for)
4
+ class_variable_set :@@wrapper_for,
5
+ Hash.new { |cache, type_casting| cache[type_casting] = wrapper_for[*type_casting] }
6
+ end
7
+
8
+ def wrapper_for(*type_casting)
9
+ class_variable_get(:@@wrapper_for)[type_casting]
10
+ end
11
+
12
+ def Context(*roles, &block)
13
+ dci = self
14
+ Class.new(WrapperBased::Context) do
15
+ roles.each { |role| add_role role, dci }
16
+ class_eval(&block) unless block.nil?
17
+ end
18
+ end
19
+ end # Context::Builder class
20
+ end # WrapperBased module
@@ -1,7 +1,7 @@
1
1
  require 'set'
2
2
 
3
3
  module WrapperBased
4
- class Cast
4
+ class Context::Casting
5
5
  attr_reader :name, :dci
6
6
 
7
7
  def initialize(name, dci)
@@ -0,0 +1,20 @@
1
+ require 'forwardable'
2
+
3
+ module WrapperBased
4
+ class Context::CastingDirector
5
+ extend Forwardable
6
+ using Context::TypeCasting
7
+
8
+ def initialize(context_class)
9
+ @casts = {}
10
+ @re = context_class
11
+ end
12
+
13
+ def cast_as(role, actor)
14
+ @casts[role] = @casts[role].as_role_played_by(actor) { recast_as(role, actor) }
15
+ end
16
+
17
+ def_delegator :@re, :cast_as, :recast_as
18
+ def_delegators :@casts, :fetch, :[]
19
+ end
20
+ end
@@ -0,0 +1,27 @@
1
+ require 'delegate'
2
+
3
+ module WrapperBased
4
+ module Context::TypeCasting
5
+ refine NilClass do
6
+ def as_role_played_by(actor)
7
+ yield
8
+ end
9
+ end
10
+
11
+ refine Delegator do
12
+ def as_role_played_by(actor)
13
+ return replace_role_player_with(actor) if role_type_same_as?(actor)
14
+ yield
15
+ end
16
+
17
+ def replace_role_player_with(actor)
18
+ __setobj__(actor)
19
+ self
20
+ end
21
+
22
+ def role_type_same_as?(actor)
23
+ actor.instance_of?(__getobj__.class)
24
+ end
25
+ end
26
+ end
27
+ end
@@ -1,7 +1,7 @@
1
1
  module WrapperBased
2
2
  class Context
3
3
  def initialize(**where)
4
- @_casting = {}
4
+ @casting_director = CastingDirector.new(self.class)
5
5
  where.each { |role, player| send :"#{role}=", player }
6
6
  end
7
7
 
@@ -18,17 +18,21 @@ module WrapperBased
18
18
  class << self
19
19
  alias_method :[], :new
20
20
 
21
+ def cast_as(role, actor)
22
+ send(role).typecast(actor)
23
+ end
24
+
21
25
  protected
22
26
 
23
- def add_role(role, caster)
27
+ def add_role(role, dci)
24
28
  add_reader_for(role)
25
29
  add_writer_for(role)
26
- add_to_class(role, caster)
30
+ add_to_class_cast_for role, Casting.new(role, dci)
27
31
  end
28
32
 
29
33
  def add_reader_for(role)
30
34
  define_method(role) do
31
- @_casting.fetch(role) { raise UnassignedRole, "Role '#{role}' is missing." }
35
+ @casting_director.fetch(role) { raise UnassignedRole, "Role '#{role}' is missing.", caller }
32
36
  end
33
37
  end
34
38
 
@@ -37,19 +41,19 @@ module WrapperBased
37
41
 
38
42
  define_method(:"#{role}=") do |actor|
39
43
  instance_variable_set(role_player, actor)
40
- @_casting[role] = self.class.send(role).typecast(actor)
44
+ @casting_director.cast_as role, actor
41
45
  end
42
46
  end
43
47
 
44
- def add_to_class(role, caster)
45
- role_caster = :"@@#{role}"
48
+ def add_to_class_cast_for(role, casting)
49
+ role_casting = :"@@#{role}"
46
50
 
47
51
  singleton_class.class_eval do
48
- define_method(role) { class_variable_get role_caster }
52
+ define_method(role) { class_variable_get role_casting }
49
53
  end
50
54
 
51
- class_variable_set role_caster, caster
55
+ class_variable_set role_casting, casting
52
56
  end
53
- end # ClassMethods module
57
+ end # class methods
54
58
  end # Context class
55
59
  end # WrapperBased module
@@ -1,21 +1,4 @@
1
- module WrapperBased
2
- class DCI < Module
3
- def initialize(wrapper_for = FORWARDING)
4
- @@wrapper_for = Hash.new do |cache, type_casting|
5
- cache[type_casting] = wrapper_for[*type_casting]
6
- end unless defined? @@wrapper_for
1
+ require "wrapper_based"
2
+ require "type_wrapper"
7
3
 
8
- def wrapper_for(*type_casting)
9
- @@wrapper_for[type_casting]
10
- end unless defined? self.wrapper_for
11
-
12
- def Context(*roles, &block)
13
- dci = self
14
- Class.new(WrapperBased::Context) do
15
- roles.each { |role| add_role role, WrapperBased::Cast.new(role, dci) }
16
- class_eval(&block) unless block.nil?
17
- end
18
- end unless defined? self.Context
19
- end # initialize method
20
- end # DCI class
21
- end # WrapperBased module
4
+ DCI = WrapperBased::Context::Builder.new(TypeWrapper)
@@ -1,3 +1,3 @@
1
1
  module WrapperBased
2
- VERSION = "0.5.0"
2
+ VERSION = "1.0.0"
3
3
  end
data/lib/wrapper_based.rb CHANGED
@@ -1,21 +1,9 @@
1
1
  require "wrapper_based/version"
2
- require "wrapper_based/cast"
3
2
  require "wrapper_based/context"
4
- require "wrapper_based/dci"
5
- require "wrapper_based/decorator"
3
+ require "wrapper_based/context/builder"
4
+ require "wrapper_based/context/casting"
5
+ require "wrapper_based/context/type_casting"
6
+ require "wrapper_based/context/casting_director"
6
7
 
7
8
  module WrapperBased
8
- FORWARDING = -> type, *behaviors do
9
- Class.new(Decorator) do
10
- using Module.new { refine(type) { prepend(*behaviors.reverse) } }
11
-
12
- forwarding = behaviors.flat_map(&:public_instance_methods) - public_instance_methods
13
-
14
- forwarding.uniq.each do |meth|
15
- define_method(meth) do |*args, &block|
16
- __getobj__.send(meth, *args, &block)
17
- end
18
- end
19
- end
20
- end
21
9
  end
@@ -19,7 +19,9 @@ Gem::Specification.new do |spec|
19
19
  spec.bindir = "exe"
20
20
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
21
  spec.require_paths = ["lib"]
22
- spec.required_ruby_version = ">= 2.4.0"
22
+ spec.required_ruby_version = ">= 2.1.0"
23
+
24
+ spec.add_runtime_dependency "type_wrapper", "~> 1.0"
23
25
 
24
26
  spec.add_development_dependency "bundler", "~> 1.15"
25
27
  spec.add_development_dependency "rake", "~> 10.0"
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wrapper_based
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ritchie Paul Buitre
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-06-30 00:00:00.000000000 Z
11
+ date: 2017-07-10 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: type_wrapper
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.0'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: bundler
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -73,10 +87,12 @@ files:
73
87
  - examples/money_transfer.rb
74
88
  - examples/toy_shop.rb
75
89
  - lib/wrapper_based.rb
76
- - lib/wrapper_based/cast.rb
77
90
  - lib/wrapper_based/context.rb
91
+ - lib/wrapper_based/context/builder.rb
92
+ - lib/wrapper_based/context/casting.rb
93
+ - lib/wrapper_based/context/casting_director.rb
94
+ - lib/wrapper_based/context/type_casting.rb
78
95
  - lib/wrapper_based/dci.rb
79
- - lib/wrapper_based/decorator.rb
80
96
  - lib/wrapper_based/version.rb
81
97
  - wrapper_based.gemspec
82
98
  homepage: https://github.com/RichOrElse/wrapper-based/
@@ -91,7 +107,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
91
107
  requirements:
92
108
  - - ">="
93
109
  - !ruby/object:Gem::Version
94
- version: 2.4.0
110
+ version: 2.1.0
95
111
  required_rubygems_version: !ruby/object:Gem::Requirement
96
112
  requirements:
97
113
  - - ">="
@@ -1,13 +0,0 @@
1
- require 'delegate'
2
-
3
- module WrapperBased
4
- class Decorator < Delegator
5
- alias_method :initialize, def __setobj__(obj)
6
- @delegate_sd_obj = obj # change delegation object
7
- end
8
-
9
- alias_method :~@, def __getobj__
10
- @delegate_sd_obj # return object we are delegating to
11
- end
12
- end
13
- end