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 +4 -4
- data/README.md +11 -11
- data/examples/benchmark.rb +27 -0
- data/examples/dijkstra.rb +11 -11
- data/examples/money_transfer.rb +3 -3
- data/lib/wrapper_based/context.rb +16 -8
- data/lib/wrapper_based/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ff350bc479ae984adc21032e70fab33aea8f1ce5
|
4
|
+
data.tar.gz: 281d02a14989a788d9b53ba6eb0b3f41c1ed86a6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
37
|
+
GetDistance[within: self].of(path)
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
41
41
|
module CurrentIntersection
|
42
|
-
def neighbors(
|
43
|
-
east_neighbor =
|
44
|
-
south_neighbor =
|
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
|
-
|
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
|
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
|
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
|
-
|
82
|
+
shortest_path_from_city_neighbors << @from
|
83
83
|
end
|
84
84
|
|
85
85
|
private
|
86
86
|
|
87
|
-
def
|
87
|
+
def shortest_path_from_city_neighbors
|
88
88
|
from.
|
89
|
-
neighbors(
|
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
|
data/examples/dijkstra.rb
CHANGED
@@ -9,22 +9,22 @@ module Map
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def distance_of(path)
|
12
|
-
|
12
|
+
GetDistance[within: self].of(path)
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
16
|
module CurrentIntersection
|
17
|
-
def neighbors(
|
18
|
-
east_neighbor =
|
19
|
-
south_neighbor =
|
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
|
-
|
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
|
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
|
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
|
-
|
57
|
+
shortest_path_from_city_neighbors << @from
|
58
58
|
end
|
59
59
|
|
60
60
|
private
|
61
61
|
|
62
|
-
def
|
62
|
+
def shortest_path_from_city_neighbors
|
63
63
|
from.
|
64
|
-
neighbors(
|
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
|
data/examples/money_transfer.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
|
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
|
-
|
26
|
+
LogTransaction["Withdraw", amount, from.number]
|
27
27
|
end
|
28
28
|
|
29
29
|
def deposit(amount)
|
30
30
|
to.increase_balance_by(amount)
|
31
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
32
|
-
|
33
|
-
|
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
|
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.
|
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-
|
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
|