wrapper_based 0.5.0 → 1.0.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: 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