wrapper_based 0.3.0 → 0.4.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: 860bb92daa686c64bcb7807cc743a0e1f41d892d
4
- data.tar.gz: 15482c725f191bc7fa9a336fddebbc10e71a3051
3
+ metadata.gz: ff350bc479ae984adc21032e70fab33aea8f1ce5
4
+ data.tar.gz: 281d02a14989a788d9b53ba6eb0b3f41c1ed86a6
5
5
  SHA512:
6
- metadata.gz: ab743403db24d5918f180321e2c6f45c93f5284c7d9bfab97038cf19b399abcb2d0f28870e98db9d0dc854d99e79a1afafa38e35288ccdb3c63285ab6718fbcb
7
- data.tar.gz: 817c1a3a8494e3d259df6602f59eaf15a6931208ea530333201895dc8c8c1bb124160e4e75712ca62bb675ca515654330a6d1795bc700949af2096a4b950012a
6
+ metadata.gz: 4b0f9bab7b974ff6a94b8be0e91e63f779f8df8c0fd6e6d959a4d28632c91ef85ad5382a0ec6521ed572d82e060e0e9add15117370649ebd298d5d669eac8330
7
+ data.tar.gz: 696723ab1d675cf1acb1cb9a6765823853bb84b31e95fe689dd4fcfe7afdf427c8bf9f00f7594c1316129675443366b22c3c424f2a760a457ab39722d4524b83
data/README.md CHANGED
@@ -34,22 +34,22 @@ module Map
34
34
  end
35
35
 
36
36
  def distance_of(path)
37
- Distance[within: self].of(path)
37
+ GetDistance[within: self].of(path)
38
38
  end
39
39
  end
40
40
 
41
41
  module CurrentIntersection
42
- def neighbors(nearest:)
43
- east_neighbor = nearest.east_neighbor_of(self)
44
- south_neighbor = nearest.south_neighbor_of(self)
45
- [south_neighbor, east_neighbor].compact
42
+ def neighbors(manhattan:)
43
+ east_neighbor = manhattan.east_neighbor_of(self)
44
+ south_neighbor = manhattan.south_neighbor_of(self)
45
+ [south_neighbor, east_neighbor].compact # excludes nil neighbors
46
46
  end
47
47
  end
48
48
 
49
49
  module DestinationNode
50
50
  def shortest_path(from:, within:)
51
51
  return [self] if equal? from
52
- Shortest[to: self, from: from, city: within].path
52
+ FindShortest[to: self, from: from, city: within].path
53
53
  end
54
54
  end
55
55
 
@@ -57,7 +57,7 @@ end
57
57
 
58
58
  DCI = WrapperBased::DCI.new unless defined? DCI
59
59
 
60
- class Distance < DCI::Context(:within)
60
+ class GetDistance < DCI::Context(:within)
61
61
  within.as Map
62
62
 
63
63
  def between(from, to)
@@ -69,7 +69,7 @@ class Distance < DCI::Context(:within)
69
69
  end
70
70
  end
71
71
 
72
- class Shortest < DCI::Context(:from, :to, :city)
72
+ class FindShortest < DCI::Context(:from, :to, :city)
73
73
  from.as CurrentIntersection
74
74
  to.as DestinationNode
75
75
  city.as Map
@@ -79,14 +79,14 @@ class Shortest < DCI::Context(:from, :to, :city)
79
79
  end
80
80
 
81
81
  def path
82
- _shortest_path + [@from]
82
+ shortest_path_from_city_neighbors << @from
83
83
  end
84
84
 
85
85
  private
86
86
 
87
- def _shortest_path
87
+ def shortest_path_from_city_neighbors
88
88
  from.
89
- neighbors(nearest: @city).
89
+ neighbors(manhattan: @city).
90
90
  map { |neighbor| to.shortest_path from: neighbor, within: @city }.
91
91
  min_by { |path| city.distance_of path }
92
92
  end
@@ -0,0 +1,27 @@
1
+ # Derived from https://tonyarcieri.com/dci-in-ruby-is-completely-broken
2
+ require 'rubygems'
3
+ require 'benchmark/ips'
4
+ require 'wrapper_based'
5
+
6
+ class ExampleClass
7
+ def foo; 42; end
8
+ end
9
+
10
+ module ExampleMixin
11
+ def foo; 43; end
12
+ end
13
+
14
+ wrapper = WrapperBased::FORWARDING[ExampleClass, ExampleMixin]
15
+
16
+ Benchmark.ips do |bm|
17
+ bm.report("without dci") { ExampleClass.new.foo }
18
+ bm.report("with wrapper") do
19
+ wrapper.new(ExampleClass.new).foo
20
+ end
21
+ bm.report("with extend") do
22
+ obj = ExampleClass.new
23
+ obj.extend(ExampleMixin)
24
+ obj.foo
25
+ end
26
+ bm.compare!
27
+ end
@@ -9,22 +9,22 @@ module Map
9
9
  end
10
10
 
11
11
  def distance_of(path)
12
- Distance[within: self].of(path)
12
+ GetDistance[within: self].of(path)
13
13
  end
14
14
  end
15
15
 
16
16
  module CurrentIntersection
17
- def neighbors(nearest:)
18
- east_neighbor = nearest.east_neighbor_of(self)
19
- south_neighbor = nearest.south_neighbor_of(self)
20
- [south_neighbor, east_neighbor].compact
17
+ def neighbors(manhattan:)
18
+ east_neighbor = manhattan.east_neighbor_of(self)
19
+ south_neighbor = manhattan.south_neighbor_of(self)
20
+ [south_neighbor, east_neighbor].compact # excludes nil neighbors
21
21
  end
22
22
  end
23
23
 
24
24
  module DestinationNode
25
25
  def shortest_path(from:, within:)
26
26
  return [self] if equal? from
27
- Shortest[to: self, from: from, city: within].path
27
+ FindShortest[to: self, from: from, city: within].path
28
28
  end
29
29
  end
30
30
 
@@ -32,7 +32,7 @@ end
32
32
 
33
33
  DCI = WrapperBased::DCI.new unless defined? DCI
34
34
 
35
- class Distance < DCI::Context(:within)
35
+ class GetDistance < DCI::Context(:within)
36
36
  within.as Map
37
37
 
38
38
  def between(from, to)
@@ -44,7 +44,7 @@ class Distance < DCI::Context(:within)
44
44
  end
45
45
  end
46
46
 
47
- class Shortest < DCI::Context(:from, :to, :city)
47
+ class FindShortest < DCI::Context(:from, :to, :city)
48
48
  from.as CurrentIntersection
49
49
  to.as DestinationNode
50
50
  city.as Map
@@ -54,14 +54,14 @@ class Shortest < DCI::Context(:from, :to, :city)
54
54
  end
55
55
 
56
56
  def path
57
- _shortest_path + [@from]
57
+ shortest_path_from_city_neighbors << @from
58
58
  end
59
59
 
60
60
  private
61
61
 
62
- def _shortest_path
62
+ def shortest_path_from_city_neighbors
63
63
  from.
64
- neighbors(nearest: @city).
64
+ neighbors(manhattan: @city).
65
65
  map { |neighbor| to.shortest_path from: neighbor, within: @city }.
66
66
  min_by { |path| city.distance_of path }
67
67
  end
@@ -1,4 +1,4 @@
1
- Log = method(:puts)
1
+ LogTransaction = method(:puts)
2
2
  Account = Struct.new(:number, :balance)
3
3
  NotEnoughFunds = Class.new(StandardError)
4
4
 
@@ -23,12 +23,12 @@ class TransferMoney < DCI::Context(:from, :to)
23
23
 
24
24
  def withdraw(amount)
25
25
  from.decrease_balance_by(amount)
26
- Log["Withdraw", amount, from]
26
+ LogTransaction["Withdraw", amount, from.number]
27
27
  end
28
28
 
29
29
  def deposit(amount)
30
30
  to.increase_balance_by(amount)
31
- Log["Deposit", amount, to]
31
+ LogTransaction["Deposit", amount, to.number]
32
32
  end
33
33
 
34
34
  def call(amount:)
@@ -1,7 +1,8 @@
1
1
  module WrapperBased
2
2
  class Context
3
3
  def initialize(**where)
4
- where.each { |role, player| instance_variable_set :"@#{role}", player }
4
+ @_casting = {}
5
+ where.each { |role, player| send :"#{role}=", player }
5
6
  end
6
7
 
7
8
  def to_proc
@@ -12,25 +13,32 @@ module WrapperBased
12
13
  call(*args, &block)
13
14
  end
14
15
 
16
+ UnassignedRole = StandardError
17
+
15
18
  class << self
16
19
  def [](**role_cast, &block)
17
20
  context_class = Class.new(self, &block)
18
21
 
19
22
  context_class.class_eval do
20
23
  role_cast.each do |role, cast|
21
- class_variable_set :"@@#{role}", cast
24
+ role_player = :"@#{role}"
25
+
26
+ define_method(:"#{role}=") do |actor|
27
+ instance_variable_set(role_player, actor)
28
+ @_casting[role] = context_class.send(role).typecast(actor)
29
+ end
30
+
22
31
  define_method(role) do
23
- self.class.class_variable_get(:"@@#{role}").
24
- typecast instance_variable_get(:"@#{role}")
32
+ @_casting.fetch(role) { fail UnassignedRole, "Role '#{role}' is missing." }
25
33
  end
26
34
  end
27
35
  end
28
36
 
29
37
  context_class.singleton_class.class_eval do
30
- role_cast.each do |role, _|
31
- define_method(role) do
32
- class_variable_get :"@@#{role}"
33
- end
38
+ role_cast.each do |role, cast|
39
+ variable = :"@@#{role}"
40
+ define_method(role) { class_variable_get variable }
41
+ context_class.class_variable_set variable, cast
34
42
  end
35
43
 
36
44
  alias_method :[], :new
@@ -1,3 +1,3 @@
1
1
  module WrapperBased
2
- VERSION = "0.3.0"
2
+ VERSION = "0.4.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wrapper_based
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.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-16 00:00:00.000000000 Z
11
+ date: 2017-06-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -67,6 +67,7 @@ files:
67
67
  - Rakefile
68
68
  - bin/console
69
69
  - bin/setup
70
+ - examples/benchmark.rb
70
71
  - examples/dijkstra.rb
71
72
  - examples/dijkstra/data.rb
72
73
  - examples/money_transfer.rb