dci-ruby 1.0.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +52 -0
- data/Gemfile +3 -12
- data/Gemfile.lock +7 -16
- data/LICENSE.txt +1 -1
- data/README.rdoc +20 -21
- data/Rakefile +1 -49
- data/dci-ruby.gemspec +17 -60
- data/examples/money_transfer.rb +17 -7
- data/lib/dci-ruby.rb +4 -93
- data/lib/dci-ruby/dci/context.rb +95 -0
- data/lib/dci-ruby/dci/role.rb +49 -0
- data/lib/dci-ruby/version.rb +3 -0
- data/spec/context_spec.rb +59 -23
- data/spec/interaction_spec.rb +18 -7
- data/spec/role_spec.rb +19 -6
- data/spec/roleplayers_spec.rb +42 -11
- metadata +24 -77
- data/VERSION +0 -1
data/.gitignore
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
# rcov generated
|
2
|
+
coverage
|
3
|
+
coverage.data
|
4
|
+
|
5
|
+
# rdoc generated
|
6
|
+
rdoc
|
7
|
+
|
8
|
+
# yard generated
|
9
|
+
doc
|
10
|
+
.yardoc
|
11
|
+
|
12
|
+
# bundler
|
13
|
+
.bundle
|
14
|
+
|
15
|
+
# jeweler generated
|
16
|
+
pkg
|
17
|
+
|
18
|
+
# Have editor/IDE/OS specific files you need to ignore? Consider using a global gitignore:
|
19
|
+
#
|
20
|
+
# * Create a file at ~/.gitignore
|
21
|
+
# * Include files you want ignored
|
22
|
+
# * Run: git config --global core.excludesfile ~/.gitignore
|
23
|
+
#
|
24
|
+
# After doing this, these files will be ignored in all your git projects,
|
25
|
+
# saving you from having to 'pollute' every project you touch with them
|
26
|
+
#
|
27
|
+
# Not sure what to needs to be ignored for particular editors/OSes? Here's some ideas to get you started. (Remember, remove the leading # of the line)
|
28
|
+
#
|
29
|
+
# For MacOS:
|
30
|
+
#
|
31
|
+
#.DS_Store
|
32
|
+
|
33
|
+
# For TextMate
|
34
|
+
#*.tmproj
|
35
|
+
#tmtags
|
36
|
+
|
37
|
+
# For emacs:
|
38
|
+
#*~
|
39
|
+
#\#*
|
40
|
+
#.\#*
|
41
|
+
|
42
|
+
# For vim:
|
43
|
+
#*.swp
|
44
|
+
|
45
|
+
# For redcar:
|
46
|
+
#.redcar
|
47
|
+
|
48
|
+
# For rubinius:
|
49
|
+
#*.rbc
|
50
|
+
|
51
|
+
# RVM
|
52
|
+
.rvmrc
|
data/Gemfile
CHANGED
@@ -1,14 +1,5 @@
|
|
1
1
|
source "http://rubygems.org"
|
2
|
-
# Add dependencies required to use your gem here.
|
3
|
-
# Example:
|
4
|
-
# gem "activesupport", ">= 2.3.5"
|
5
2
|
|
6
|
-
#
|
7
|
-
#
|
8
|
-
|
9
|
-
gem "rspec", "~> 2"
|
10
|
-
gem "rdoc", "~> 3.12"
|
11
|
-
gem "bundler", "~> 1.0.0"
|
12
|
-
gem "jeweler", "~> 1.8.4"
|
13
|
-
gem "rcov", ">= 0"
|
14
|
-
end
|
3
|
+
# It's better to specify your gem's dependencies (both, those of development and those of production) in foodie.gemspec
|
4
|
+
gemspec # This makes bundle read dci-ruby.gemspec file to add its dependencies in their corresponding groups
|
5
|
+
|
data/Gemfile.lock
CHANGED
@@ -1,18 +1,12 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
dci-ruby (2.0.0)
|
5
|
+
|
1
6
|
GEM
|
2
7
|
remote: http://rubygems.org/
|
3
8
|
specs:
|
4
9
|
diff-lcs (1.1.3)
|
5
|
-
git (1.2.5)
|
6
|
-
jeweler (1.8.4)
|
7
|
-
bundler (~> 1.0)
|
8
|
-
git (>= 1.2.5)
|
9
|
-
rake
|
10
|
-
rdoc
|
11
|
-
json (1.7.5)
|
12
|
-
rake (0.9.2.2)
|
13
|
-
rcov (1.0.0)
|
14
|
-
rdoc (3.12)
|
15
|
-
json (~> 1.4)
|
16
10
|
rspec (2.11.0)
|
17
11
|
rspec-core (~> 2.11.0)
|
18
12
|
rspec-expectations (~> 2.11.0)
|
@@ -26,8 +20,5 @@ PLATFORMS
|
|
26
20
|
ruby
|
27
21
|
|
28
22
|
DEPENDENCIES
|
29
|
-
|
30
|
-
|
31
|
-
rcov
|
32
|
-
rdoc (~> 3.12)
|
33
|
-
rspec (~> 2)
|
23
|
+
dci-ruby!
|
24
|
+
rspec (~> 2.0)
|
data/LICENSE.txt
CHANGED
data/README.rdoc
CHANGED
@@ -8,65 +8,64 @@ This gem makes Data-Context-Interaction paradigm ready to be used in your Ruby a
|
|
8
8
|
|
9
9
|
Install as usual, either with rubygems
|
10
10
|
gem install dci-ruby
|
11
|
-
|
11
|
+
|
12
|
+
or including it in your Gemfile and running bundle install:
|
12
13
|
# Gemfile
|
13
14
|
gem "dci-ruby"
|
14
15
|
|
15
16
|
|
16
17
|
== Use
|
17
18
|
|
18
|
-
dci-ruby gives you the class Context to inherit from to create your own contexts:
|
19
|
+
dci-ruby gives you the class DCI::Context to inherit from to create your own contexts:
|
19
20
|
|
20
|
-
class MoneyTransfer < Context
|
21
|
+
class MoneyTransfer < DCI::Context
|
21
22
|
|
22
23
|
# Roles
|
23
24
|
role :source_account do
|
24
25
|
def transfer(amount)
|
25
|
-
|
26
|
-
target_account.get_transfer(amount)
|
26
|
+
player.balance -= amount
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
30
|
role :target_account do
|
31
31
|
def get_transfer(amount)
|
32
|
-
balance += amount
|
32
|
+
player.balance += amount
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
36
|
# Interactions
|
37
|
-
def run(amount)
|
37
|
+
def run(amount=default_amount)
|
38
38
|
source_account.transfer(amount)
|
39
|
-
|
40
|
-
|
41
|
-
def run_default
|
42
|
-
source_account.transfer(default_amount)
|
39
|
+
target_account.get_transfer(amount)
|
43
40
|
end
|
44
41
|
end
|
45
42
|
|
46
43
|
Every context defines some roles to be played by external objects (players) and their interactions. This way
|
47
|
-
you have the
|
48
|
-
|
44
|
+
you have all the agents and operations in a user case wrapped in just one entity instead of spreaded throughout the
|
45
|
+
application code.
|
49
46
|
|
50
|
-
Use the defined contexts
|
47
|
+
Use the defined contexts, instantiating them wherever you need in your code:
|
51
48
|
|
52
49
|
MoneyTransfer.new(:source_account => Account.new(1),
|
53
50
|
:target_account => Account.new(2)).run(100)
|
54
51
|
|
55
|
-
|
56
|
-
|
57
|
-
|
52
|
+
In a context instance, every role instanciates an object (roleplayer) that gathers the behaviour defined inside its role,
|
53
|
+
and that roleplayer object has private access to the original object adopting the role (player): the Account instances above are players.
|
54
|
+
Instances of MoneyTransfer::SourceAccount and MoneyTransfer::TargetAccount accessible inside MoneyTransfer.new via
|
55
|
+
the private instance_methods #source_account and #target_account are roleplayers.
|
56
|
+
Also, every roleplayer has private access to the rest of roleplayers in its context.
|
57
|
+
|
58
58
|
When instanciating a Context, the extra no-role pairs given as arguments are read-only attributes accessible inside the instance:
|
59
59
|
|
60
60
|
MoneyTransfer.new(:source_account => Account.new(1),
|
61
61
|
:target_account => Account.new(2),
|
62
|
-
:default_amount => 500).
|
62
|
+
:default_amount => 500).run
|
63
63
|
|
64
|
-
here, default_amount is not a
|
64
|
+
here, default_amount is not a player (has no associated role) but is still accessible in the interactions.
|
65
65
|
|
66
66
|
See the examples[https://github.com/ltello/dci-ruby/tree/master/examples] folder for examples of use and the DCI-Sample[https://github.com/ltello/DCI-Sample] repository for a sample application using DCI through this gem.
|
67
67
|
|
68
68
|
== Copyright
|
69
69
|
|
70
|
-
Copyright (c) 2012 Lorenzo Tello. See LICENSE.txt for
|
71
|
-
further details.
|
70
|
+
Copyright (c) 2012, 2013 Lorenzo Tello. See LICENSE.txt for further details.
|
72
71
|
|
data/Rakefile
CHANGED
@@ -1,49 +1 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require 'rubygems'
|
4
|
-
require 'bundler'
|
5
|
-
begin
|
6
|
-
Bundler.setup(:default, :development)
|
7
|
-
rescue Bundler::BundlerError => e
|
8
|
-
$stderr.puts e.message
|
9
|
-
$stderr.puts "Run `bundle install` to install missing gems"
|
10
|
-
exit e.status_code
|
11
|
-
end
|
12
|
-
require 'rake'
|
13
|
-
|
14
|
-
require 'jeweler'
|
15
|
-
Jeweler::Tasks.new do |gem|
|
16
|
-
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
17
|
-
gem.name = "dci-ruby"
|
18
|
-
gem.homepage = "http://github.com/ltello/dci-ruby"
|
19
|
-
gem.license = "MIT"
|
20
|
-
gem.summary = %Q{Make DCI paradigm available to Ruby applications by enabling developers defining contexts suclassing the new class Context. You define roles inside the definition. Match roles and player objects in context instanciation.}
|
21
|
-
gem.description = %Q{Make DCI paradigm available to Ruby applications}
|
22
|
-
gem.email = "ltello8a@gmail.com"
|
23
|
-
gem.authors = ["Lorenzo Tello"]
|
24
|
-
# dependencies defined in Gemfile
|
25
|
-
end
|
26
|
-
Jeweler::RubygemsDotOrgTasks.new
|
27
|
-
|
28
|
-
require 'rspec/core'
|
29
|
-
require 'rspec/core/rake_task'
|
30
|
-
RSpec::Core::RakeTask.new(:spec) do |spec|
|
31
|
-
spec.pattern = FileList['spec/**/*_spec.rb']
|
32
|
-
end
|
33
|
-
|
34
|
-
RSpec::Core::RakeTask.new(:rcov) do |spec|
|
35
|
-
spec.pattern = 'spec/**/*_spec.rb'
|
36
|
-
spec.rcov = true
|
37
|
-
end
|
38
|
-
|
39
|
-
task :default => :spec
|
40
|
-
|
41
|
-
require 'rdoc/task'
|
42
|
-
Rake::RDocTask.new do |rdoc|
|
43
|
-
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
44
|
-
|
45
|
-
rdoc.rdoc_dir = 'rdoc'
|
46
|
-
rdoc.title = "dci-ruby #{version}"
|
47
|
-
rdoc.rdoc_files.include('README*')
|
48
|
-
rdoc.rdoc_files.include('lib/**/*.rb')
|
49
|
-
end
|
1
|
+
require "bundler/gem_tasks"
|
data/dci-ruby.gemspec
CHANGED
@@ -1,68 +1,25 @@
|
|
1
|
-
# Generated by jeweler
|
2
|
-
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
-
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
1
|
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "dci-ruby/version"
|
5
4
|
|
6
5
|
Gem::Specification.new do |s|
|
7
|
-
s.name
|
8
|
-
s.version
|
9
|
-
|
10
|
-
s.
|
11
|
-
s.
|
12
|
-
s.
|
6
|
+
s.name = "dci-ruby"
|
7
|
+
s.version = DCI::VERSION
|
8
|
+
s.authors = ["Lorenzo Tello"]
|
9
|
+
s.email = ["ltello8a@gmail.com"]
|
10
|
+
s.homepage = "http://github.com/ltello/dci-ruby"
|
11
|
+
s.summary = "Make DCI paradigm available to Ruby applications by enabling developers defining contexts subclassing the class DCI::Context. You define roles inside the definition. Match roles and player objects in context instantiation."
|
13
12
|
s.description = "Make DCI paradigm available to Ruby applications"
|
14
|
-
s.email = "ltello8a@gmail.com"
|
15
|
-
s.extra_rdoc_files = [
|
16
|
-
"LICENSE.txt",
|
17
|
-
"README.rdoc"
|
18
|
-
]
|
19
|
-
s.files = [
|
20
|
-
".document",
|
21
|
-
".rspec",
|
22
|
-
"Gemfile",
|
23
|
-
"Gemfile.lock",
|
24
|
-
"LICENSE.txt",
|
25
|
-
"README.rdoc",
|
26
|
-
"Rakefile",
|
27
|
-
"VERSION",
|
28
|
-
"dci-ruby.gemspec",
|
29
|
-
"examples/money_transfer.rb",
|
30
|
-
"lib/dci-ruby.rb",
|
31
|
-
"lib/dci-ruby/kernel.rb",
|
32
|
-
"spec/context_spec.rb",
|
33
|
-
"spec/interaction_spec.rb",
|
34
|
-
"spec/role_spec.rb",
|
35
|
-
"spec/roleplayers_spec.rb",
|
36
|
-
"spec/spec_helper.rb"
|
37
|
-
]
|
38
|
-
s.homepage = "http://github.com/ltello/dci-ruby"
|
39
13
|
s.licenses = ["MIT"]
|
40
|
-
s.require_paths = ["lib"]
|
41
|
-
s.rubygems_version = "1.8.24"
|
42
|
-
s.summary = "Make DCI paradigm available to Ruby applications by enabling developers defining contexts suclassing the new class Context. You define roles inside the definition. Match roles and player objects in context instanciation."
|
43
14
|
|
44
|
-
|
45
|
-
s.specification_version = 3
|
15
|
+
s.rubyforge_project = "dci-ruby"
|
46
16
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
s.add_development_dependency(%q<jeweler>, ["~> 1.8.4"])
|
52
|
-
s.add_development_dependency(%q<rcov>, [">= 0"])
|
53
|
-
else
|
54
|
-
s.add_dependency(%q<rspec>, ["~> 2"])
|
55
|
-
s.add_dependency(%q<rdoc>, ["~> 3.12"])
|
56
|
-
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
57
|
-
s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
|
58
|
-
s.add_dependency(%q<rcov>, [">= 0"])
|
59
|
-
end
|
60
|
-
else
|
61
|
-
s.add_dependency(%q<rspec>, ["~> 2"])
|
62
|
-
s.add_dependency(%q<rdoc>, ["~> 3.12"])
|
63
|
-
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
64
|
-
s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
|
65
|
-
s.add_dependency(%q<rcov>, [">= 0"])
|
66
|
-
end
|
67
|
-
end
|
17
|
+
s.files = `git ls-files`.split("\n")
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
|
+
s.require_paths = ["lib"]
|
68
21
|
|
22
|
+
# specify any dependencies here; for example:
|
23
|
+
s.add_development_dependency "rspec", "~> 2.0"
|
24
|
+
# s.add_runtime_dependency "rest-client"
|
25
|
+
end
|
data/examples/money_transfer.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'forwardable'
|
1
2
|
require 'dci-ruby'
|
2
3
|
|
3
4
|
|
@@ -5,27 +6,36 @@ class CheckingAccount
|
|
5
6
|
attr_reader :account_id
|
6
7
|
attr_accessor :balance
|
7
8
|
|
8
|
-
def initialize(account_id)
|
9
|
-
@account_id, @balance = account_id,
|
9
|
+
def initialize(account_id, initial_balance=0)
|
10
|
+
@account_id, @balance = account_id, initial_balance
|
10
11
|
end
|
11
12
|
end
|
12
13
|
|
13
14
|
|
14
|
-
class MoneyTransferContext < Context
|
15
|
+
class MoneyTransferContext < DCI::Context
|
15
16
|
|
16
17
|
# Roles Definitions
|
17
18
|
|
18
19
|
role :source_account do
|
20
|
+
extend ::Forwardable
|
21
|
+
def_delegators :player, :account_id, :balance, :balance=
|
22
|
+
|
19
23
|
def run_transfer_of(amount)
|
20
24
|
self.balance -= amount
|
21
|
-
puts "
|
25
|
+
puts "\tAccount(\##{account_id}) sent #{amount}€ to Account(\##{target_account.account_id})."
|
22
26
|
end
|
23
27
|
end
|
24
28
|
|
25
29
|
role :target_account do
|
30
|
+
#[:account_id, :balance, :balance=].each {|field| define_method(field) {|*args| player.send(field, *args)}}
|
31
|
+
def account_id; player.account_id end
|
32
|
+
def balance; player.balance end
|
33
|
+
def balance=(amount) player.balance=(amount) end
|
34
|
+
private :balance=
|
35
|
+
|
26
36
|
def run_transfer_of(amount)
|
27
37
|
self.balance += amount
|
28
|
-
puts "
|
38
|
+
puts "\tAccount(\##{account_id}) received #{amount}€ from Account(\##{source_account.account_id})."
|
29
39
|
end
|
30
40
|
end
|
31
41
|
|
@@ -47,10 +57,10 @@ class MoneyTransferContext < Context
|
|
47
57
|
end
|
48
58
|
|
49
59
|
def balances
|
50
|
-
accounts.map {|account| "
|
60
|
+
accounts.map {|account| "#{account.balance}€"}.join(' - ')
|
51
61
|
end
|
52
62
|
end
|
53
63
|
|
54
|
-
MoneyTransferContext.new(:source_account => CheckingAccount.new(1),
|
64
|
+
MoneyTransferContext.new(:source_account => CheckingAccount.new(1, 500),
|
55
65
|
:target_account => CheckingAccount.new(2),
|
56
66
|
:amount => 500).run
|
data/lib/dci-ruby.rb
CHANGED
@@ -1,96 +1,7 @@
|
|
1
|
-
require '
|
1
|
+
require 'dci-ruby/version'
|
2
2
|
require 'dci-ruby/kernel'
|
3
|
+
require 'dci-ruby/dci/context'
|
3
4
|
|
4
|
-
|
5
|
-
class Context
|
6
|
-
|
7
|
-
class << self
|
8
|
-
|
9
|
-
# Every subclass of Context has is own class and instance method roles defined.
|
10
|
-
# The instance method delegates value to the class.
|
11
|
-
def inherited(subklass)
|
12
|
-
subklass.class_eval do
|
13
|
-
def self.roles; {} end
|
14
|
-
def roles; self.class.roles end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
|
19
|
-
private
|
20
|
-
|
21
|
-
# The macro role is defined to allow a subclass of Context to define roles in its definition.
|
22
|
-
# Every new role redefines the role class method to contain a hash accumulating all defined roles in that subclass.
|
23
|
-
# An accessor to the object playing the new role is also defined and available in every instance of the context subclass.
|
24
|
-
def role(role_key, &block)
|
25
|
-
raise "role name must be a symbol" unless role_key.is_a?(Symbol)
|
26
|
-
updated_roles = roles.merge(role_key => Module.new(&block))
|
27
|
-
singleton_class.class_exec(updated_roles) do |new_roles|
|
28
|
-
remove_method(:roles) rescue nil
|
29
|
-
define_method(:roles) { new_roles }
|
30
|
-
end
|
31
|
-
attr_reader role_key
|
32
|
-
end
|
33
|
-
|
34
|
-
end
|
35
|
-
|
36
|
-
|
37
|
-
# Instances of a defined subclass of Context are initialized checking first that all subclass defined roles
|
38
|
-
# are provided in the creation invocation raising an error if any of them is missing.
|
39
|
-
# Once the previous check is met, every object playing in the context instance is associated to the stated role.
|
40
|
-
# Non players args are associated to instance_variables and readers defined.
|
41
|
-
def initialize(args={})
|
42
|
-
check_all_roles_provided_in!(args)
|
43
|
-
players, noplayers = args.partition {|key, value| roles.keys.include?(key)}.map {|group| Hash[*group.flatten]}
|
44
|
-
assign_roles_to_players(players)
|
45
|
-
define_attr_readers_for_no_players(noplayers)
|
46
|
-
end
|
47
|
-
|
48
|
-
|
49
|
-
private
|
50
|
-
|
51
|
-
# Checks there is an intented player for every role.
|
52
|
-
# Raises and error message in case of missing roles.
|
53
|
-
def check_all_roles_provided_in!(players={})
|
54
|
-
missing_roles = missing_roles(players)
|
55
|
-
raise "missing roles #{missing_roles}" unless missing_roles.empty?
|
56
|
-
end
|
57
|
-
|
58
|
-
# The list of roles with no player provided
|
59
|
-
def missing_roles(players={})
|
60
|
-
(roles.keys - players.keys)
|
61
|
-
end
|
62
|
-
|
63
|
-
# Associates every role to the intended player.
|
64
|
-
def assign_roles_to_players(players={})
|
65
|
-
roles.keys.each do |role_key|
|
66
|
-
assign_role_to_player(role_key, players[role_key])
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
# Associates a role to an intended player:
|
71
|
-
# - The object to play the role extends the defined module for that role, so it now respond to the methods
|
72
|
-
# defined in the role definition.
|
73
|
-
# - The object to play the role has access to the context it is playing.
|
74
|
-
# - The object to play the role has access to the rest of players in its context.
|
75
|
-
# - The context instance has access to this new player through a new instance variable defined with the name of the role.
|
76
|
-
def assign_role_to_player(role_key, player)
|
77
|
-
role_module = roles[role_key]
|
78
|
-
other_role_keys = roles.keys - [role_key]
|
79
|
-
player.extend(role_module, ::SingleForwardable)
|
80
|
-
player.singleton_class.class_exec(self) do |context|
|
81
|
-
define_method(:context) {context}
|
82
|
-
end
|
83
|
-
player.def_delegators(:context, *other_role_keys)
|
84
|
-
instance_variable_set(:"@#{role_key}", player)
|
85
|
-
end
|
86
|
-
|
87
|
-
def define_attr_readers_for_no_players(vars={})
|
88
|
-
vars.each do |name, value|
|
89
|
-
instance_variable_set(:"@#{name}", value)
|
90
|
-
singleton_class.class_exec(name.to_sym) do |varkey|
|
91
|
-
attr_reader varkey
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
end
|
5
|
+
module DCI
|
96
6
|
end
|
7
|
+
|
@@ -0,0 +1,95 @@
|
|
1
|
+
require 'dci-ruby/dci/role'
|
2
|
+
|
3
|
+
module DCI
|
4
|
+
|
5
|
+
class Context
|
6
|
+
|
7
|
+
class << self
|
8
|
+
|
9
|
+
# Every subclass of Context has is own class and instance method roles defined.
|
10
|
+
# The instance method delegates value to the class.
|
11
|
+
def inherited(subklass)
|
12
|
+
subklass.class_eval do
|
13
|
+
@roles ||= {}
|
14
|
+
def self.roles; @roles end
|
15
|
+
def roles; self.class.roles end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
# The macro role is defined to allow a subclass of Context to define roles in its definition.
|
23
|
+
# Every new role redefines the role class method to contain a hash accumulating all defined roles in that subclass.
|
24
|
+
# An accessor to the object playing the new role is also defined and available in every instance of the context subclass.
|
25
|
+
def role(role_key, &block)
|
26
|
+
raise "role name must be a symbol" unless role_key.is_a?(Symbol)
|
27
|
+
new_klass_name = role_key.to_s.split(/\_+/).map(&:capitalize).join('')
|
28
|
+
const_set(new_klass_name, Class.new(::DCI::Role, &block))
|
29
|
+
roles.merge!(role_key => const_get(new_klass_name.to_sym))
|
30
|
+
attr_reader role_key
|
31
|
+
private role_key
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
# Instances of a defined subclass of Context are initialized checking first that all subclass defined roles
|
38
|
+
# are provided in the creation invocation raising an error if any of them is missing.
|
39
|
+
# Once the previous check is met, every object playing in the context instance is associated to the stated role.
|
40
|
+
# Non players args are associated to instance_variables and readers defined.
|
41
|
+
def initialize(args={})
|
42
|
+
check_all_roles_provided_in!(args)
|
43
|
+
players, noplayers = args.partition {|key, value| roles.has_key?(key)}.map {|group| Hash[*group.flatten]}
|
44
|
+
assign_roles_to_players(players)
|
45
|
+
define_readers_for_no_players(noplayers)
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
# Checks there is a player for each role.
|
52
|
+
# Raises and error message in case of missing roles.
|
53
|
+
def check_all_roles_provided_in!(players={})
|
54
|
+
missing_roles = missing_roles(players)
|
55
|
+
raise "missing roles #{missing_roles}" unless missing_roles.empty?
|
56
|
+
end
|
57
|
+
|
58
|
+
# The list of roles with no player provided
|
59
|
+
def missing_roles(players={})
|
60
|
+
(roles.keys - players.keys)
|
61
|
+
end
|
62
|
+
|
63
|
+
# Associates every role to the intended player.
|
64
|
+
def assign_roles_to_players(players={})
|
65
|
+
roles.keys.each do |role_key|
|
66
|
+
assign_role_to_player(role_key, players[role_key])
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# Associates a role to an intended player:
|
71
|
+
# - A new role instance is created from the associated role_key class and the player to get that role.
|
72
|
+
# - The new role instance has access to the context it is playing.
|
73
|
+
# - The new role instance has access to the rest of players in its context through instance methods named after their role keys.
|
74
|
+
# - The context instance has access to this new role instance through an instance method named after the role key.
|
75
|
+
def assign_role_to_player(role_key, player)
|
76
|
+
role_klass = roles[role_key]
|
77
|
+
other_role_keys = roles.keys - [role_key]
|
78
|
+
role_instance = role_klass.new(:player => player, :context => self, :role_mate_keys => other_role_keys)
|
79
|
+
instance_variable_set(:"@#{role_key}", role_instance)
|
80
|
+
end
|
81
|
+
|
82
|
+
# For each given pair in vars, define a private method named the key that returns the entry associated value.
|
83
|
+
def define_readers_for_no_players(vars={})
|
84
|
+
vars.each do |name, value|
|
85
|
+
instance_variable_set(:"@#{name}", value)
|
86
|
+
singleton_class.class_exec(name.to_sym) do |varkey|
|
87
|
+
private
|
88
|
+
attr_reader varkey
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module DCI
|
2
|
+
|
3
|
+
class Role
|
4
|
+
|
5
|
+
class << self
|
6
|
+
|
7
|
+
# Make this class abstract: will not allow create instances.
|
8
|
+
def new(*args, &block)
|
9
|
+
raise 'This class is meant to be abstract and not instantiable' if self == DCI::Role
|
10
|
+
super
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
|
15
|
+
# Opts:
|
16
|
+
# player => the object to adquire this role,
|
17
|
+
# context => the context instance in which this role instance will play
|
18
|
+
# role_mate_keys => list of keys of the rest of roles playing in the given context
|
19
|
+
def initialize(opts={})
|
20
|
+
@player = opts[:player]
|
21
|
+
@context = opts[:context]
|
22
|
+
define_role_mate_methods!(opts[:role_mate_keys])
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
# Make the original object playing the role accessible only inside role definition code!
|
29
|
+
def player
|
30
|
+
@player
|
31
|
+
end
|
32
|
+
|
33
|
+
# For each role in the context, define a method so inside a role you can access all the others.
|
34
|
+
def define_role_mate_methods!(role_mate_keys)
|
35
|
+
self.class.class_exec(role_mate_keys) do |other_role_keys|
|
36
|
+
other_role_keys.each do |role_key|
|
37
|
+
if not private_method_defined?(role_key)
|
38
|
+
define_method(role_key) do
|
39
|
+
@context.send(role_key)
|
40
|
+
end
|
41
|
+
private role_key
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
data/spec/context_spec.rb
CHANGED
@@ -1,12 +1,14 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
2
|
|
3
|
-
describe Context do
|
3
|
+
describe DCI::Context do
|
4
4
|
|
5
|
-
context "Definition" do
|
6
|
-
context "When
|
5
|
+
context "Definition:" do
|
6
|
+
context "When Inheriting from DCI::Context..." do
|
7
7
|
before(:all) do
|
8
|
-
class
|
9
|
-
role :
|
8
|
+
class TestingDefinitionContext < DCI::Context
|
9
|
+
role :role_name do
|
10
|
+
def role_name_method
|
11
|
+
end
|
10
12
|
end
|
11
13
|
|
12
14
|
def interaction1
|
@@ -14,17 +16,42 @@ describe Context do
|
|
14
16
|
end
|
15
17
|
end
|
16
18
|
|
17
|
-
it("
|
18
|
-
it("...in which the developer can define roles...")
|
19
|
-
|
20
|
-
|
19
|
+
it("...a new dci context is ready to be used...") {TestingDefinitionContext.superclass.should be(DCI::Context)}
|
20
|
+
it("...in which the developer can define roles...") do
|
21
|
+
TestingDefinitionContext.private_methods.should include("role")
|
22
|
+
end
|
23
|
+
it("...but privately inside the subclass.") {TestingDefinitionContext.should_not respond_to(:role)}
|
24
|
+
|
25
|
+
it("A role is defined calling the private macro #role with a role_key and a block defining the specific methods of the role.") do
|
26
|
+
TestingDefinitionContext.roles.size.should be(1)
|
27
|
+
TestingDefinitionContext.roles.keys.should include(:role_name)
|
28
|
+
end
|
29
|
+
|
30
|
+
it("The #roles public class_and_instance_method will return a hash with pairs (role_key => ContextSubclass::Rolekey)...") do
|
31
|
+
TestingDefinitionContext.roles.should eq({:role_name => TestingDefinitionContext::RoleName})
|
32
|
+
TestingDefinitionContext.new(:role_name => Object.new).roles.should eq(:role_name => TestingDefinitionContext::RoleName)
|
33
|
+
end
|
34
|
+
it("... where every ContextSubclass::Rolekey is a new class created at load time,...") do
|
35
|
+
TestingDefinitionContext.roles[:role_name].should be_a(Class)
|
36
|
+
TestingDefinitionContext.roles[:role_name].should be(TestingDefinitionContext::RoleName)
|
37
|
+
end
|
38
|
+
it("... named after the associated role_key...") do
|
39
|
+
TestingDefinitionContext.const_defined?(:RoleName).should be(true)
|
40
|
+
end
|
41
|
+
it("... and defined after the block given to the associated role in its definition.") do
|
42
|
+
TestingDefinitionContext::RoleName.public_instance_methods.should include("role_name_method")
|
43
|
+
end
|
44
|
+
|
45
|
+
it("Inside the context subclass, the developer defines context methods (instance methods) that act as interactions.") do
|
46
|
+
TestingDefinitionContext.public_instance_methods(false).should include('interaction1')
|
47
|
+
end
|
21
48
|
end
|
22
49
|
end
|
23
50
|
|
24
|
-
context "Use" do
|
25
|
-
context "To use a Context" do
|
51
|
+
context "Use:" do
|
52
|
+
context "To use a Context..." do
|
26
53
|
before(:all) do
|
27
|
-
class
|
54
|
+
class TestingUseContext < DCI::Context
|
28
55
|
role :role1 do
|
29
56
|
end
|
30
57
|
role :role2 do
|
@@ -39,23 +66,32 @@ describe Context do
|
|
39
66
|
end
|
40
67
|
end
|
41
68
|
@player1, @player2 = Object.new, Object.new
|
42
|
-
@
|
69
|
+
@context_instance_1 = TestingUseContext.new(:role1 => @player1, :role2 => @player2)
|
70
|
+
@context_instance_2 = TestingUseContext.new(:role1 => @player1, :role2 => @player2, :extra_arg => :extra)
|
43
71
|
end
|
44
72
|
|
45
|
-
it("
|
46
|
-
it("...providing
|
47
|
-
expect {
|
73
|
+
it("...instanciate it from its correspondig DCI::Context subclass...") {@context_instance_1.should be_a(TestingUseContext)}
|
74
|
+
it("...providing pairs of type :rolekey1 => player1 as arguments...") do
|
75
|
+
expect {TestingUseContext.new(@player1, @player2)}.to raise_error
|
48
76
|
end
|
49
|
-
it("...with ALL
|
50
|
-
expect {
|
77
|
+
it("...with ALL the role_keys in the subclass as keys...") do
|
78
|
+
expect {TestingUseContext.new(:role1 => @player1)}.to raise_error('missing roles role2')
|
51
79
|
end
|
52
80
|
it("...and the objects to play those roles as values.") do
|
53
|
-
[@player1, @player2].should include(@
|
81
|
+
[@player1, @player2].should include(@context_instance_1.send(:role1).send(:player), @context_instance_1.send(:role2).send(:player))
|
82
|
+
end
|
83
|
+
|
84
|
+
it("...You can also include other extra pairs as arguments...") do
|
85
|
+
expect {TestingUseContext.new(:role1 => @player1, :role2 => @player2, :extra_arg => :extra)}.not_to raise_error
|
86
|
+
end
|
87
|
+
|
88
|
+
|
89
|
+
it("Once instanciated...") {@context_instance_1.should be_a(TestingUseContext)}
|
90
|
+
it("...you call an interaction (instance method) on it") do
|
91
|
+
@context_instance_1.should respond_to(:interaction1)
|
54
92
|
end
|
55
|
-
it("
|
56
|
-
|
57
|
-
it("...to start interaction among roleplayers inside the context") do
|
58
|
-
@example_context.interaction2.should be_instance_of(Fixnum)
|
93
|
+
it("...to start interaction among roleplayers inside the context.") do
|
94
|
+
@context_instance_1.interaction2.should be_instance_of(Fixnum)
|
59
95
|
end
|
60
96
|
|
61
97
|
end
|
data/spec/interaction_spec.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
2
|
|
3
|
-
describe 'Interaction' do
|
3
|
+
describe 'Interaction:' do
|
4
4
|
|
5
|
-
context "Inside a
|
5
|
+
context "Inside a Context instance method(interaction)..." do
|
6
6
|
before(:all) do
|
7
|
-
class
|
7
|
+
class TestingInteractionsContext < DCI::Context
|
8
8
|
role :role1 do
|
9
9
|
end
|
10
10
|
role :role2 do
|
@@ -15,12 +15,23 @@ describe 'Interaction' do
|
|
15
15
|
end
|
16
16
|
end
|
17
17
|
@player1, @player2 = Object.new, Object.new
|
18
|
-
@
|
18
|
+
@test_interactions_context = TestingInteractionsContext.new(:role1 => @player1, :role2 => @player2, :extra_arg => :extra)
|
19
19
|
end
|
20
20
|
|
21
|
-
it("
|
22
|
-
|
23
|
-
|
21
|
+
it("...the developer has access to all the roleplayers...") do
|
22
|
+
@test_interactions_context.interaction1.should be_a(TestingInteractionsContext::Role1)
|
23
|
+
@test_interactions_context.send(:role2).should be_a(TestingInteractionsContext::Role2)
|
24
|
+
end
|
25
|
+
it("...via private instance methods named after their role keys.") do
|
26
|
+
@test_interactions_context.private_methods(false).should include('role1', 'role2')
|
27
|
+
end
|
24
28
|
|
29
|
+
it("He also have access to extra args received in the instantiation of its context...") do
|
30
|
+
@test_interactions_context.send(:extra_arg).should be(:extra)
|
31
|
+
end
|
32
|
+
it("...through private methods named after their keys.") do
|
33
|
+
@test_interactions_context.private_methods(false).should include('extra_arg')
|
34
|
+
end
|
35
|
+
end
|
25
36
|
|
26
37
|
end
|
data/spec/role_spec.rb
CHANGED
@@ -2,19 +2,32 @@ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
|
2
2
|
|
3
3
|
describe 'Role' do
|
4
4
|
|
5
|
-
context "When defining roles inside a Context subclass..." do
|
5
|
+
context "When defining roles inside a DCI::Context subclass..." do
|
6
6
|
before(:all) do
|
7
|
-
class
|
7
|
+
class TestingRoleContext < DCI::Context
|
8
8
|
role :rolename do
|
9
9
|
end
|
10
10
|
role :anotherrolename do
|
11
11
|
end
|
12
12
|
end
|
13
13
|
end
|
14
|
-
it("
|
15
|
-
|
16
|
-
|
17
|
-
it("
|
14
|
+
it("...you can define as many as you want.") do
|
15
|
+
TestingRoleContext.roles.keys.size.should eql(2)
|
16
|
+
end
|
17
|
+
it("Each rolename must be provided as a symbol...") do
|
18
|
+
TestingRoleContext.roles.keys.should include(:rolename, :anotherrolename)
|
19
|
+
end
|
20
|
+
it("...and not as a string.") do
|
21
|
+
expect do
|
22
|
+
class TestingRoleContext < DCI::Context
|
23
|
+
role "rolename" do
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end.to raise_error
|
27
|
+
end
|
28
|
+
it("A block defining rolemethods must be provided as well.") do
|
29
|
+
TestingRoleContext.roles[:rolename].should be_a(Class)
|
30
|
+
end
|
18
31
|
end
|
19
32
|
|
20
33
|
end
|
data/spec/roleplayers_spec.rb
CHANGED
@@ -3,18 +3,25 @@ require 'ostruct'
|
|
3
3
|
|
4
4
|
describe 'RolePlayers' do
|
5
5
|
|
6
|
-
context "Are Ruby objects inside a context instance" do
|
6
|
+
context "Are Ruby objects inside a context instance..." do
|
7
7
|
before(:all) do
|
8
|
-
class
|
8
|
+
class TestingRoleplayersContext < DCI::Context
|
9
9
|
role :role1 do
|
10
10
|
def rolemethod1
|
11
11
|
:rolemethod1_executed
|
12
12
|
end
|
13
13
|
end
|
14
|
+
|
14
15
|
role :role2 do
|
15
16
|
def rolemethod2
|
16
17
|
role1
|
17
18
|
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def private_rolemethod2
|
23
|
+
:public_rolemethod_return_value
|
24
|
+
end
|
18
25
|
end
|
19
26
|
|
20
27
|
def interaction1
|
@@ -25,21 +32,45 @@ describe 'RolePlayers' do
|
|
25
32
|
role1.object_id - role2.object_id
|
26
33
|
end
|
27
34
|
end
|
28
|
-
@player1, @player2 = OpenStruct.new(:
|
29
|
-
@
|
35
|
+
@player1, @player2 = OpenStruct.new(:name => 'player1'), OpenStruct.new(:name => 'player2')
|
36
|
+
@testing_roleplayers_context = TestingRoleplayersContext.new(:role1 => @player1, :role2 => @player2)
|
37
|
+
end
|
38
|
+
|
39
|
+
it("...each one instance of the class defined after the role he plays...") do
|
40
|
+
@testing_roleplayers_context.send(:role1).should be_a(TestingRoleplayersContext::Role1)
|
41
|
+
@testing_roleplayers_context.send(:role2).should be_a(TestingRoleplayersContext::Role2)
|
42
|
+
end
|
43
|
+
it("...so they adquire the public instance methods defined in their role...") do
|
44
|
+
@testing_roleplayers_context.send(:role1).public_methods(false).should include('rolemethod1')
|
45
|
+
@testing_roleplayers_context.send(:role1).should respond_to(:rolemethod1)
|
46
|
+
@testing_roleplayers_context.send(:role1).rolemethod1.should eql(:rolemethod1_executed)
|
47
|
+
end
|
48
|
+
it("...as well as the private ones.") do
|
49
|
+
@testing_roleplayers_context.send(:role2).private_methods(false).should include('private_rolemethod2')
|
50
|
+
@testing_roleplayers_context.send(:role2).should_not respond_to(:private_rolemethod2)
|
51
|
+
@testing_roleplayers_context.send(:role2).send(:private_rolemethod2).should eql(:public_rolemethod_return_value)
|
30
52
|
end
|
31
53
|
|
32
|
-
it("
|
33
|
-
@
|
54
|
+
it("Also, through the private method #player") do
|
55
|
+
@testing_roleplayers_context.send(:role1).private_methods.should include('player')
|
34
56
|
end
|
35
|
-
it("...
|
36
|
-
@
|
57
|
+
it("...they have access to the original object playing the role...") do
|
58
|
+
@testing_roleplayers_context.send(:role1).send(:player).should be(@player1)
|
59
|
+
@testing_roleplayers_context.send(:role2).send(:player).should be(@player2)
|
37
60
|
end
|
38
|
-
it("
|
39
|
-
@
|
61
|
+
it("...and, therefore, its public interface.") do
|
62
|
+
@testing_roleplayers_context.send(:role1).send(:player).name.should eq('player1')
|
63
|
+
@testing_roleplayers_context.send(:role2).send(:player).name.should eq('player2')
|
64
|
+
end
|
65
|
+
|
66
|
+
it("Roleplayers have private access to other roleplayers in their context...") do
|
67
|
+
@testing_roleplayers_context.send(:role2).private_methods(false).should include('role1')
|
68
|
+
@testing_roleplayers_context.send(:role2).rolemethod2.should eql(@testing_roleplayers_context.send(:role1))
|
40
69
|
end
|
41
70
|
it("...and even the context itself.") do
|
42
|
-
@
|
71
|
+
expect {@testing_roleplayers_context.send(:role2).send(:context)}.to raise_error(NoMethodError)
|
72
|
+
@testing_roleplayers_context.send(:role2).instance_variables.should include('@context')
|
73
|
+
@testing_roleplayers_context.send(:role2).instance_variable_get(:@context).should be(@testing_roleplayers_context)
|
43
74
|
end
|
44
75
|
end
|
45
76
|
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dci-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 15
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
|
-
-
|
7
|
+
- 2
|
8
8
|
- 0
|
9
9
|
- 0
|
10
|
-
version:
|
10
|
+
version: 2.0.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Lorenzo Tello
|
@@ -15,105 +15,48 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date:
|
18
|
+
date: 2013-10-29 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
22
|
-
none: false
|
23
|
-
requirements:
|
24
|
-
- - ~>
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
hash: 7
|
27
|
-
segments:
|
28
|
-
- 2
|
29
|
-
version: "2"
|
30
|
-
version_requirements: *id001
|
31
21
|
name: rspec
|
32
22
|
prerelease: false
|
33
|
-
|
34
|
-
- !ruby/object:Gem::Dependency
|
35
|
-
requirement: &id002 !ruby/object:Gem::Requirement
|
36
|
-
none: false
|
37
|
-
requirements:
|
38
|
-
- - ~>
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
hash: 31
|
41
|
-
segments:
|
42
|
-
- 3
|
43
|
-
- 12
|
44
|
-
version: "3.12"
|
45
|
-
version_requirements: *id002
|
46
|
-
name: rdoc
|
47
|
-
prerelease: false
|
48
|
-
type: :development
|
49
|
-
- !ruby/object:Gem::Dependency
|
50
|
-
requirement: &id003 !ruby/object:Gem::Requirement
|
51
|
-
none: false
|
52
|
-
requirements:
|
53
|
-
- - ~>
|
54
|
-
- !ruby/object:Gem::Version
|
55
|
-
hash: 23
|
56
|
-
segments:
|
57
|
-
- 1
|
58
|
-
- 0
|
59
|
-
- 0
|
60
|
-
version: 1.0.0
|
61
|
-
version_requirements: *id003
|
62
|
-
name: bundler
|
63
|
-
prerelease: false
|
64
|
-
type: :development
|
65
|
-
- !ruby/object:Gem::Dependency
|
66
|
-
requirement: &id004 !ruby/object:Gem::Requirement
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
67
24
|
none: false
|
68
25
|
requirements:
|
69
26
|
- - ~>
|
70
|
-
- !ruby/object:Gem::Version
|
71
|
-
hash: 63
|
72
|
-
segments:
|
73
|
-
- 1
|
74
|
-
- 8
|
75
|
-
- 4
|
76
|
-
version: 1.8.4
|
77
|
-
version_requirements: *id004
|
78
|
-
name: jeweler
|
79
|
-
prerelease: false
|
80
|
-
type: :development
|
81
|
-
- !ruby/object:Gem::Dependency
|
82
|
-
requirement: &id005 !ruby/object:Gem::Requirement
|
83
|
-
none: false
|
84
|
-
requirements:
|
85
|
-
- - ">="
|
86
27
|
- !ruby/object:Gem::Version
|
87
28
|
hash: 3
|
88
29
|
segments:
|
30
|
+
- 2
|
89
31
|
- 0
|
90
|
-
version: "0"
|
91
|
-
version_requirements: *id005
|
92
|
-
name: rcov
|
93
|
-
prerelease: false
|
32
|
+
version: "2.0"
|
94
33
|
type: :development
|
34
|
+
version_requirements: *id001
|
95
35
|
description: Make DCI paradigm available to Ruby applications
|
96
|
-
email:
|
36
|
+
email:
|
37
|
+
- ltello8a@gmail.com
|
97
38
|
executables: []
|
98
39
|
|
99
40
|
extensions: []
|
100
41
|
|
101
|
-
extra_rdoc_files:
|
102
|
-
|
103
|
-
- README.rdoc
|
42
|
+
extra_rdoc_files: []
|
43
|
+
|
104
44
|
files:
|
105
45
|
- .document
|
46
|
+
- .gitignore
|
106
47
|
- .rspec
|
107
48
|
- Gemfile
|
108
49
|
- Gemfile.lock
|
109
50
|
- LICENSE.txt
|
110
51
|
- README.rdoc
|
111
52
|
- Rakefile
|
112
|
-
- VERSION
|
113
53
|
- dci-ruby.gemspec
|
114
54
|
- examples/money_transfer.rb
|
115
55
|
- lib/dci-ruby.rb
|
56
|
+
- lib/dci-ruby/dci/context.rb
|
57
|
+
- lib/dci-ruby/dci/role.rb
|
116
58
|
- lib/dci-ruby/kernel.rb
|
59
|
+
- lib/dci-ruby/version.rb
|
117
60
|
- spec/context_spec.rb
|
118
61
|
- spec/interaction_spec.rb
|
119
62
|
- spec/role_spec.rb
|
@@ -147,10 +90,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
147
90
|
version: "0"
|
148
91
|
requirements: []
|
149
92
|
|
150
|
-
rubyforge_project:
|
93
|
+
rubyforge_project: dci-ruby
|
151
94
|
rubygems_version: 1.8.24
|
152
95
|
signing_key:
|
153
96
|
specification_version: 3
|
154
|
-
summary: Make DCI paradigm available to Ruby applications by enabling developers defining contexts
|
155
|
-
test_files:
|
156
|
-
|
97
|
+
summary: Make DCI paradigm available to Ruby applications by enabling developers defining contexts subclassing the class DCI::Context. You define roles inside the definition. Match roles and player objects in context instantiation.
|
98
|
+
test_files:
|
99
|
+
- spec/context_spec.rb
|
100
|
+
- spec/interaction_spec.rb
|
101
|
+
- spec/role_spec.rb
|
102
|
+
- spec/roleplayers_spec.rb
|
103
|
+
- spec/spec_helper.rb
|
data/VERSION
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
1.0.0
|