greedy-dci 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: af0618dbc065577434a26c6f9d7de53d7bedc7ee
4
+ data.tar.gz: 265129f6201d8bb82876bb11f9ebd77b303857a1
5
+ SHA512:
6
+ metadata.gz: 2def0e4909bdac5170b8d12cd77680859dd30e6c36872afc2184a6d2a6cda1501eb1d0f48618cf8bf39cae50953c5b2f8fff085feb83182c94e734afece9dfbe
7
+ data.tar.gz: b6a388520724432c9525f77b8c08bbaa8a969a15c7ce253921ea7b4b5e4783e2db272929079cbe10da6a52d53a10c0668f8168958a43a28086112868f4bcb387
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.travis.yml ADDED
@@ -0,0 +1,7 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.4.0
5
+ - 2.3.0
6
+
7
+ before_install: gem install bundler -v 1.14.6
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in greedy-dci.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2017 Ritchie Paul Buitre
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,106 @@
1
+ # Greedy::DCI
2
+
3
+ A Toolkit for rapid prototyping of interactors, use cases and service objects, using the DCI paradigm.
4
+ This implementation consumes excessive resources (hence the name) and is **not recommended for production use**.
5
+
6
+ ## What is DCI?
7
+
8
+ DCI (Data, context and interaction) is a new Role-Based Paradigm for specifying collaborating objects.
9
+ Trygve Reenskaug is the originator best known for formulating the MVC (model–view–controller) pattern.
10
+
11
+ You can read more about DCI at the following links:
12
+
13
+ * http://dci.github.io/
14
+ * http://dci-in-ruby.info/
15
+ * http://fulloo.info/
16
+
17
+ ## Installation
18
+
19
+ Add this line to your application's Gemfile:
20
+
21
+ ```ruby
22
+ gem 'greedy-dci'
23
+ ```
24
+
25
+ And then execute:
26
+
27
+ $ bundle
28
+
29
+ Or install it yourself as:
30
+
31
+ $ gem install greedy-dci
32
+
33
+ ## Usage
34
+
35
+ ```ruby
36
+ require 'greedy-dci'
37
+
38
+ # Data
39
+
40
+ Purchase = Struct.new(:toy, :buyer)
41
+ Deliver = Struct.new(:toy, :recipient, :purchase, :status)
42
+
43
+ # Behaviors
44
+
45
+ module Buyer
46
+ def buy(toy)
47
+ Purchase.new toy, self
48
+ end
49
+ end
50
+
51
+ module Recipient
52
+ def receive(purchased)
53
+ Deliver.new purchased.toy, self, purchased, :pending
54
+ end
55
+ end
56
+
57
+ # Contexts
58
+
59
+ PurchaseToy = Greedy.context { |purchaser|
60
+ using purchaser.as Buyer
61
+ using purchaser.as Recipient
62
+
63
+ def call(toy)
64
+ purchased = purchaser.buy toy
65
+ purchaser.receive purchased
66
+ end
67
+ }
68
+
69
+
70
+ GiftToy = Greedy.context { |gifter, giftee|
71
+ using gifter.as Buyer
72
+ using giftee.as Recipient
73
+
74
+ def call(toy)
75
+ gift = gifter.buy toy
76
+ giftee.receive gift
77
+ end
78
+ }
79
+
80
+ # Interactions
81
+
82
+ finn_purchase_toy = PurchaseToy[purchaser: 'Finn']
83
+ finn_purchase_toy.call 'Rusty sword'
84
+ finn_purchase_toy.('Armor of Zeldron')
85
+ finn_purchase_toy['The Enchiridion']
86
+
87
+ ['Card Wars', 'Ice Ninja Manual', 'Bacon'].each &GiftToy[gifter: 'Jake', giftee: 'Finn']
88
+ ```
89
+
90
+ [View more examples](https://github.com/RichOrElse/greedy-dci/tree/master/examples)
91
+
92
+ ## Development
93
+
94
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
95
+
96
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
97
+
98
+ ## Contributing
99
+
100
+ Bug reports and pull requests are welcome on GitHub at https://github.com/RichOrElse/greedy-dci.
101
+
102
+
103
+ ## License
104
+
105
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
106
+
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ t.libs << "lib"
7
+ t.test_files = FileList['test/**/*_test.rb']
8
+ end
9
+
10
+ task :default => :test
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "greedy/dci"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,223 @@
1
+ # Source: http://fulloo.info/Examples/RubyExamples/Dijkstra/DijkstraListing.html
2
+
3
+ def infinity
4
+ 2**(0.size * 8 -2) -1
5
+ end
6
+
7
+ #
8
+ # Consider street corners on a Manhattan grid. We want to find the
9
+ # minimal path from the most northeast city to the most
10
+ # southeast city. Use Dijstra's algorithm
11
+ #
12
+
13
+ # Data classes
14
+
15
+ Edge = Struct.new :from, :to
16
+
17
+ class Node
18
+ attr_reader :name
19
+
20
+ def initialize(name)
21
+ @name = name
22
+ end
23
+
24
+ def eql?(another_node)
25
+ # Nodes are == equal if they have the same name. This is explicitly
26
+ # defined here to call out the importance of the difference between
27
+ # object equality and identity
28
+ name == another_node.name
29
+ end
30
+
31
+ def ==(another_node)
32
+ # Equality used in the Map algorithms is object identity
33
+ super
34
+ end
35
+ end
36
+
37
+ #
38
+ # --- Geometry is the interface to the data class that has all
39
+ # --- the information about the map. This is kind of silly in Ruby
40
+ #
41
+
42
+ # In the domain model we have a general model of streets and avenues. The notions of
43
+ # an east and south neighbor are not part of the domain model, but are germane to
44
+ # the Dijkstra problem. Though they evaluate to the same thing we use different
45
+ # names to reflect these two different (mental) models of Manhattan streets.
46
+ class ManhattanGeometry
47
+ def east_neighbor_of(a) end
48
+ def south_neighbor_of(a) end
49
+ def root; end
50
+ def destination; end
51
+ def nodes; @nodes end
52
+ end
53
+
54
+ class ManhattanGeometry1 < ManhattanGeometry
55
+ def initialize
56
+ super
57
+
58
+ @nodes, @distances = [], {}
59
+
60
+ names = %w(a b c d a b g h i)
61
+
62
+ 3.times do |i|
63
+ 3.times do |j|
64
+ @nodes << Node.new(names[(i*3)+j])
65
+ end
66
+ end
67
+
68
+ # Aliases to help set up the grid. Grid is of Manhattan form:
69
+ #
70
+ # a - 2 - b - 3 - c
71
+ # | | |
72
+ # 1 2 1
73
+ # | | |
74
+ # d - 1 - e - 1 - f
75
+ # | |
76
+ # 2 4
77
+ # | |
78
+ # g - 1 - h - 2 - i
79
+ #
80
+
81
+ %w(a b c d e f g h i).each_with_index do |name, index|
82
+ instance_variable_set :"@#{name}", @nodes[index]
83
+ end
84
+
85
+ 9.times do |i|
86
+ 9.times do |j|
87
+ @distances[Edge.new(@nodes[i], @nodes[j])] = infinity
88
+ end
89
+ end
90
+
91
+ @distances[Edge.new(@a, @b)] = 2
92
+ @distances[Edge.new(@b, @c)] = 3
93
+ @distances[Edge.new(@c, @f)] = 1
94
+ @distances[Edge.new(@f, @i)] = 4
95
+ @distances[Edge.new(@b, @e)] = 2
96
+ @distances[Edge.new(@e, @f)] = 1
97
+ @distances[Edge.new(@a, @d)] = 1
98
+ @distances[Edge.new(@d, @g)] = 2
99
+ @distances[Edge.new(@g, @h)] = 1
100
+ @distances[Edge.new(@h, @i)] = 2
101
+ @distances[Edge.new(@d, @e)] = 1
102
+ @distances.freeze
103
+
104
+ @next_down_the_street_from = {}
105
+ @next_down_the_street_from[@a] = @b
106
+ @next_down_the_street_from[@b] = @c
107
+ @next_down_the_street_from[@d] = @e
108
+ @next_down_the_street_from[@e] = @f
109
+ @next_down_the_street_from[@g] = @h
110
+ @next_down_the_street_from[@h] = @i
111
+ @next_down_the_street_from.freeze
112
+
113
+ @next_along_the_avenue_from = Hash.new
114
+ @next_along_the_avenue_from[@a] = @d
115
+ @next_along_the_avenue_from[@b] = @e
116
+ @next_along_the_avenue_from[@c] = @f
117
+ @next_along_the_avenue_from[@d] = @g
118
+ @next_along_the_avenue_from[@f] = @i
119
+ @next_along_the_avenue_from.freeze
120
+ end
121
+
122
+ def east_neighbor_of(a)
123
+ @next_down_the_street_from[a]
124
+ end
125
+
126
+ def south_neighbor_of(a)
127
+ @next_along_the_avenue_from[a]
128
+ end
129
+
130
+ def root; @a end
131
+ def destination; @i end
132
+ end
133
+
134
+ class ManhattanGeometry2 < ManhattanGeometry
135
+ def initialize
136
+ super
137
+
138
+ @nodes = %w(a b c d a b g h i j k).map { |name| Node.new name }
139
+
140
+ # Aliases to help set up the grid. Grid is of Manhattan form:
141
+ #
142
+ # a - 2 - b - 3 - c - 1 - j
143
+ # | | | |
144
+ # 1 2 1 |
145
+ # | | | |
146
+ # d - 1 - e - 1 - f 1
147
+ # | | |
148
+ # 2 4 |
149
+ # | | |
150
+ # g - 1 - h - 2 - i - 2 - k
151
+
152
+ @a = @nodes[0]
153
+ @b = @nodes[1]
154
+ @c = @nodes[2]
155
+ @d = @nodes[3]
156
+ @e = @nodes[4]
157
+ @f = @nodes[5]
158
+ @g = @nodes[6]
159
+ @h = @nodes[7]
160
+ @i = @nodes[8]
161
+ @j = @nodes[9]
162
+ @k = @nodes[10]
163
+
164
+ @distances = {}
165
+ @nodes.each do |i|
166
+ @nodes.each do |j|
167
+ @distances[Edge.new(i, j)] = infinity
168
+ end
169
+ end
170
+
171
+ @distances[Edge.new(@a, @b)] = 2
172
+ @distances[Edge.new(@b, @c)] = 3
173
+ @distances[Edge.new(@c, @f)] = 1
174
+ @distances[Edge.new(@f, @i)] = 4
175
+ @distances[Edge.new(@b, @e)] = 2
176
+ @distances[Edge.new(@e, @f)] = 1
177
+ @distances[Edge.new(@a, @d)] = 1
178
+ @distances[Edge.new(@d, @g)] = 2
179
+ @distances[Edge.new(@g, @h)] = 1
180
+ @distances[Edge.new(@h, @i)] = 2
181
+ @distances[Edge.new(@d, @e)] = 1
182
+ @distances[Edge.new(@c, @j)] = 1
183
+ @distances[Edge.new(@j, @k)] = 1
184
+ @distances[Edge.new(@i, @k)] = 2
185
+ @distances.freeze
186
+
187
+ @next_down_the_street_from = {}
188
+ @next_down_the_street_from[@a] = @b
189
+ @next_down_the_street_from[@b] = @c
190
+ @next_down_the_street_from[@c] = @j
191
+ @next_down_the_street_from[@d] = @e
192
+ @next_down_the_street_from[@e] = @f
193
+ @next_down_the_street_from[@g] = @h
194
+ @next_down_the_street_from[@h] = @i
195
+ @next_down_the_street_from[@i] = @k
196
+ @next_down_the_street_from.freeze
197
+
198
+ @next_along_the_avenue_from = {}
199
+ @next_along_the_avenue_from[@a] = @d
200
+ @next_along_the_avenue_from[@b] = @e
201
+ @next_along_the_avenue_from[@c] = @f
202
+ @next_along_the_avenue_from[@d] = @g
203
+ @next_along_the_avenue_from[@f] = @i
204
+ @next_along_the_avenue_from[@j] = @k
205
+ @next_along_the_avenue_from.freeze
206
+ end
207
+
208
+ def east_neighbor_of(a)
209
+ @next_down_the_street_from[a]
210
+ end
211
+
212
+ def south_neighbor_of(a)
213
+ @next_along_the_avenue_from[a]
214
+ end
215
+
216
+ def root
217
+ @a
218
+ end
219
+
220
+ def destination
221
+ @k
222
+ end
223
+ end
@@ -0,0 +1,68 @@
1
+ require_relative 'dijkstra/data'
2
+ # See https://github.com/RichOrElse/greedy-dci/blob/master/test/dijkstra_test.rb
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
+ Distance[within: self].of(path)
13
+ end
14
+ end
15
+
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
21
+ end
22
+ end
23
+
24
+ module DestinationNode
25
+ def shortest_path(from:, within:)
26
+ return [self] if equal? from
27
+ Shortest[from: from, to: self, map: within].path
28
+ end
29
+ end
30
+
31
+ # Contexts
32
+
33
+ extend Greedy::DCI
34
+
35
+ Distance = context do |within|
36
+ using within.as Map
37
+
38
+ def between(a, b)
39
+ within.distance_between(a, b)
40
+ end
41
+
42
+ def of(path)
43
+ path.reverse.each_cons(2).inject(0) { |total, pair| total + between(*pair) }
44
+ end
45
+ end
46
+
47
+ Shortest = context do |from, to, map|
48
+ using from.as CurrentIntersection
49
+ using to.as DestinationNode
50
+ using map.as Map
51
+
52
+ def distance
53
+ map.distance_of path
54
+ end
55
+
56
+ def path
57
+ _shortest_path + [from]
58
+ end
59
+
60
+ private
61
+
62
+ def _shortest_path
63
+ from.
64
+ neighbors(nearest: map).
65
+ map { |neighbor| to.shortest_path from: neighbor, within: map }.
66
+ min_by { |path| map.distance_of path }
67
+ end
68
+ end
@@ -0,0 +1,52 @@
1
+ require 'greedy-dci'
2
+
3
+ # Data
4
+
5
+ Purchase = Struct.new(:toy, :buyer)
6
+ Deliver = Struct.new(:toy, :recipient, :purchase, :status)
7
+
8
+ # Behaviors
9
+
10
+ module Buyer
11
+ def buy(toy)
12
+ Purchase.new toy, self
13
+ end
14
+ end
15
+
16
+ module Recipient
17
+ def receive(purchased)
18
+ Deliver.new purchased.toy, self, purchased, :pending
19
+ end
20
+ end
21
+
22
+ # Contexts
23
+
24
+ PurchaseToy = Greedy.context { |purchaser|
25
+ using purchaser.as Buyer
26
+ using purchaser.as Recipient
27
+
28
+ def call(toy)
29
+ purchased = purchaser.buy toy
30
+ purchaser.receive purchased
31
+ end
32
+ }
33
+
34
+
35
+ GiftToy = Greedy.context { |gifter, giftee|
36
+ using gifter.as Buyer
37
+ using giftee.as Recipient
38
+
39
+ def call(toy)
40
+ gift = gifter.buy toy
41
+ giftee.receive gift
42
+ end
43
+ }
44
+
45
+ # Interactions
46
+
47
+ finn_purchase_toy = PurchaseToy[purchaser: 'Finn']
48
+ finn_purchase_toy.call 'Rusty sword'
49
+ finn_purchase_toy.('Armor of Zeldron')
50
+ finn_purchase_toy['The Enchiridion']
51
+
52
+ ['Card Wars', 'Ice Ninja Manual', 'Bacon'].each &GiftToy[gifter: 'Jake', giftee: 'Finn']
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'greedy/dci/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "greedy-dci"
8
+ spec.version = Greedy::DCI::VERSION
9
+ spec.authors = ["Ritchie Paul Buitre"]
10
+ spec.email = ["ritchie@richorelse.com"]
11
+
12
+ spec.summary = "A very tiny DCI (Data, context and interaction) toolkit with true ruby implementation without the boiler plate."
13
+ spec.description = "Toolkit for rapid prototyping of interactors, use cases and service objects. Using DCI (Data, context and interaction) the new programming paradigm from the inventor of the MVC pattern. This implementation consumes excessive memory (hence the name) and is not recommended for production."
14
+ spec.homepage = "https://github.com/RichOrElse/greedy-dci/"
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
18
+ f.match(%r{^(test|spec|features)/})
19
+ end
20
+ spec.bindir = "exe"
21
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
22
+ spec.require_paths = ["lib"]
23
+ spec.required_ruby_version = ">= 2.3.0"
24
+
25
+ spec.add_development_dependency "bundler", "~> 1.14"
26
+ spec.add_development_dependency "rake", "~> 10.0"
27
+ spec.add_development_dependency "minitest", "~> 5.0"
28
+ end
@@ -0,0 +1,18 @@
1
+ module Greedy
2
+ module DCI
3
+ class Role
4
+ def initialize(obj)
5
+ @obj = obj
6
+ end
7
+
8
+ def as(responsibility)
9
+ type = @obj.singleton_class
10
+ Module.new { refine(type) { prepend responsibility } }
11
+ end
12
+
13
+ def self.to_proc
14
+ method(:new).to_proc
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,5 @@
1
+ module Greedy
2
+ module DCI
3
+ VERSION = "1.0.0"
4
+ end
5
+ end
data/lib/greedy/dci.rb ADDED
@@ -0,0 +1,16 @@
1
+ require "greedy/dci/version"
2
+ require "greedy/dci/role"
3
+
4
+ module Greedy
5
+ module DCI
6
+ def context(&block)
7
+ roles = block.parameters.map &:last
8
+ -> **where do
9
+ actors = where.values_at(*roles)
10
+ Struct.new(*roles) { class_exec(*actors.map(&Role), &block) }.new *actors
11
+ end
12
+ end
13
+ end
14
+
15
+ extend DCI
16
+ end
metadata ADDED
@@ -0,0 +1,105 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: greedy-dci
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Ritchie Paul Buitre
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2017-06-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.14'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.14'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '5.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '5.0'
55
+ description: Toolkit for rapid prototyping of interactors, use cases and service objects.
56
+ Using DCI (Data, context and interaction) the new programming paradigm from the
57
+ inventor of the MVC pattern. This implementation consumes excessive memory (hence
58
+ the name) and is not recommended for production.
59
+ email:
60
+ - ritchie@richorelse.com
61
+ executables: []
62
+ extensions: []
63
+ extra_rdoc_files: []
64
+ files:
65
+ - ".gitignore"
66
+ - ".travis.yml"
67
+ - Gemfile
68
+ - LICENSE.txt
69
+ - README.md
70
+ - Rakefile
71
+ - bin/console
72
+ - bin/setup
73
+ - examples/dijkstra.rb
74
+ - examples/dijkstra/data.rb
75
+ - examples/toy_shop.rb
76
+ - greedy-dci.gemspec
77
+ - lib/greedy/dci.rb
78
+ - lib/greedy/dci/role.rb
79
+ - lib/greedy/dci/version.rb
80
+ homepage: https://github.com/RichOrElse/greedy-dci/
81
+ licenses:
82
+ - MIT
83
+ metadata: {}
84
+ post_install_message:
85
+ rdoc_options: []
86
+ require_paths:
87
+ - lib
88
+ required_ruby_version: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: 2.3.0
93
+ required_rubygems_version: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ requirements: []
99
+ rubyforge_project:
100
+ rubygems_version: 2.6.8
101
+ signing_key:
102
+ specification_version: 4
103
+ summary: A very tiny DCI (Data, context and interaction) toolkit with true ruby implementation
104
+ without the boiler plate.
105
+ test_files: []