bunraku 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Manifest.txt +39 -0
- data/README.txt +25 -0
- data/Rakefile +93 -0
- data/examples/corechain.rb +46 -0
- data/examples/person.rb +67 -0
- data/examples/person2.rb +62 -0
- data/examples/person3.rb +72 -0
- data/examples/rentalshop.rb +127 -0
- data/examples/requires.rb +50 -0
- data/examples/scope.rb +63 -0
- data/hacks/add_method_by_method_of_Class.rb +18 -0
- data/hacks/add_method_to_Class.rb +12 -0
- data/hacks/add_method_with_local_context.rb +27 -0
- data/hacks/anonymous_method.rb +37 -0
- data/hacks/class_creation_events.rb +45 -0
- data/hacks/get_nested_class.rb +22 -0
- data/hacks/hook_method.rb +50 -0
- data/hacks/method_missing_chain.rb +33 -0
- data/hacks/method_missing_chain_override.rb +39 -0
- data/hacks/pluralize.rb +24 -0
- data/lib/bunraku.rb +3 -0
- data/lib/bunraku/base.rb +9 -0
- data/lib/bunraku/class_ext.rb +37 -0
- data/lib/bunraku/core.rb +257 -0
- data/lib/bunraku/exceptions.rb +10 -0
- data/lib/bunraku/proxies.rb +121 -0
- data/lib/bunraku/utils.rb +21 -0
- data/lib/bunraku/version.rb +9 -0
- data/scripts/makemanifest.rb +20 -0
- data/scripts/uproadwebsite.sh +18 -0
- data/setup.rb +1585 -0
- data/spec/def_context_spec.rb +34 -0
- data/spec/interaction_spec.rb +127 -0
- data/spec/require_spec.rb +44 -0
- data/spec/role2_spec.rb +116 -0
- data/spec/role_spec.rb +120 -0
- data/test/test_bunraku.rb +11 -0
- data/test/test_helper.rb +2 -0
- data/website/index.html +13 -0
- metadata +94 -0
data/Manifest.txt
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
Manifest.txt
|
2
|
+
README.txt
|
3
|
+
Rakefile
|
4
|
+
examples/corechain.rb
|
5
|
+
examples/person.rb
|
6
|
+
examples/person2.rb
|
7
|
+
examples/person3.rb
|
8
|
+
examples/rentalshop.rb
|
9
|
+
examples/requires.rb
|
10
|
+
examples/scope.rb
|
11
|
+
hacks/add_method_by_method_of_Class.rb
|
12
|
+
hacks/add_method_to_Class.rb
|
13
|
+
hacks/add_method_with_local_context.rb
|
14
|
+
hacks/anonymous_method.rb
|
15
|
+
hacks/class_creation_events.rb
|
16
|
+
hacks/get_nested_class.rb
|
17
|
+
hacks/hook_method.rb
|
18
|
+
hacks/method_missing_chain.rb
|
19
|
+
hacks/method_missing_chain_override.rb
|
20
|
+
hacks/pluralize.rb
|
21
|
+
lib/bunraku.rb
|
22
|
+
lib/bunraku/base.rb
|
23
|
+
lib/bunraku/class_ext.rb
|
24
|
+
lib/bunraku/core.rb
|
25
|
+
lib/bunraku/exceptions.rb
|
26
|
+
lib/bunraku/proxies.rb
|
27
|
+
lib/bunraku/utils.rb
|
28
|
+
lib/bunraku/version.rb
|
29
|
+
scripts/makemanifest.rb
|
30
|
+
scripts/uproadwebsite.sh
|
31
|
+
setup.rb
|
32
|
+
spec/def_context_spec.rb
|
33
|
+
spec/interaction_spec.rb
|
34
|
+
spec/require_spec.rb
|
35
|
+
spec/role2_spec.rb
|
36
|
+
spec/role_spec.rb
|
37
|
+
test/test_bunraku.rb
|
38
|
+
test/test_helper.rb
|
39
|
+
website/index.html
|
data/README.txt
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
= Bunraku:
|
2
|
+
|
3
|
+
role model programming library for ruby
|
4
|
+
|
5
|
+
== usage:
|
6
|
+
* see examples/*.rb
|
7
|
+
|
8
|
+
== requires:
|
9
|
+
it supports rails environments
|
10
|
+
(now depends on gems)
|
11
|
+
* rubygems
|
12
|
+
* http://rubyforge.org/projects/rubygems
|
13
|
+
* activesupport on gems
|
14
|
+
* http://rubyforge.org/projects/activesupport
|
15
|
+
|
16
|
+
== other resource:
|
17
|
+
|
18
|
+
* setup.rb
|
19
|
+
* http://i.loveruby.net/ja/projects/setup/
|
20
|
+
* rake
|
21
|
+
* http://rake.rubyforge.org/
|
22
|
+
* hoe
|
23
|
+
* http://seattlerb.rubyforge.org/hoe/
|
24
|
+
* rspec
|
25
|
+
* http://rspec.rubyforge.org/
|
data/Rakefile
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'rake/clean'
|
4
|
+
require 'rake/testtask'
|
5
|
+
require 'rake/packagetask'
|
6
|
+
require 'rake/gempackagetask'
|
7
|
+
require 'rake/rdoctask'
|
8
|
+
require 'rake/contrib/rubyforgepublisher'
|
9
|
+
require 'fileutils'
|
10
|
+
require 'hoe'
|
11
|
+
include FileUtils
|
12
|
+
require File.join(File.dirname(__FILE__), 'lib', 'bunraku', 'version')
|
13
|
+
|
14
|
+
AUTHOR = "ichiyama" # can also be an array of Authors
|
15
|
+
EMAIL = "your contact email for bug fixes and info"
|
16
|
+
DESCRIPTION = "description of gem"
|
17
|
+
GEM_NAME = "bunraku" # what ppl will type to install your gem
|
18
|
+
RUBYFORGE_PROJECT = "bunraku" # The unix name for your project
|
19
|
+
HOMEPATH = "http://#{RUBYFORGE_PROJECT}.rubyforge.org"
|
20
|
+
|
21
|
+
|
22
|
+
NAME = "bunraku"
|
23
|
+
REV = nil
|
24
|
+
VERS = Bunraku::VERSION::STRING + (REV ? ".#{REV}" : "")
|
25
|
+
|
26
|
+
RDOC_OPTS = ['--quiet', '--title', "bunraku documentation",
|
27
|
+
"--opname", "index.html",
|
28
|
+
"--line-numbers",
|
29
|
+
"--main", "README",
|
30
|
+
"--inline-source"]
|
31
|
+
|
32
|
+
class Hoe
|
33
|
+
def extra_deps
|
34
|
+
@extra_deps.reject { |x| Array(x).first == 'hoe' }
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# Generate all the Rake tasks
|
39
|
+
# Run 'rake -T' to see list of generated tasks (from gem root directory)
|
40
|
+
hoe = Hoe.new(GEM_NAME, VERS) do |p|
|
41
|
+
p.author = AUTHOR
|
42
|
+
p.description = DESCRIPTION
|
43
|
+
p.email = EMAIL
|
44
|
+
p.summary = DESCRIPTION
|
45
|
+
p.url = HOMEPATH
|
46
|
+
p.rubyforge_name = RUBYFORGE_PROJECT if RUBYFORGE_PROJECT
|
47
|
+
p.test_globs = ["test/**/*_test.rb"]
|
48
|
+
p.clean_globs = CLEAN #An array of file patterns to delete on clean.
|
49
|
+
p.extra_deps = [['active_support']]
|
50
|
+
|
51
|
+
# == Optional
|
52
|
+
#p.changes - A description of the release's latest changes.
|
53
|
+
#p.extra_deps - An array of rubygem dependencies.
|
54
|
+
#p.spec_extras - A hash of extra values to set in the gemspec.
|
55
|
+
end
|
56
|
+
|
57
|
+
# without gem
|
58
|
+
hoe.instance_eval do
|
59
|
+
desc 'Package and upload the release to rubyforge.'
|
60
|
+
task :release => [:clean, :package] do |t|
|
61
|
+
v = ENV["VERSION"] or abort "Must supply VERSION=x.y.z"
|
62
|
+
abort "Versions don't match #{v} vs #{version}" if v != version
|
63
|
+
pkg = "pkg/#{name}-#{version}"
|
64
|
+
|
65
|
+
rf = RubyForge.new
|
66
|
+
puts "Logging in"
|
67
|
+
rf.login
|
68
|
+
|
69
|
+
c = rf.userconfig
|
70
|
+
c["release_notes"] = description if description
|
71
|
+
c["release_changes"] = changes if changes
|
72
|
+
c["preformatted"] = true
|
73
|
+
|
74
|
+
files = [(@need_tar ? "#{pkg}.tgz" : nil),
|
75
|
+
(@need_zip ? "#{pkg}.zip" : nil),
|
76
|
+
].compact
|
77
|
+
|
78
|
+
puts "Releasing #{name} v. #{version}"
|
79
|
+
rf.add_release rubyforge_name, name, version, *files
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
begin
|
84
|
+
gem "rspec"
|
85
|
+
require 'spec/rake/spectask'
|
86
|
+
desc "Run all specs"
|
87
|
+
Spec::Rake::SpecTask.new('runspecs') do |t|
|
88
|
+
t.libs << "lib"
|
89
|
+
t.libs << "spec"
|
90
|
+
t.spec_files = FileList['spec/**/*.rb']
|
91
|
+
end
|
92
|
+
ensure
|
93
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
|
2
|
+
require "bunraku"
|
3
|
+
|
4
|
+
class ContextA
|
5
|
+
as_context
|
6
|
+
class RoleA
|
7
|
+
as_role
|
8
|
+
def foo
|
9
|
+
puts "ContextA::RoleA"
|
10
|
+
core.foo()
|
11
|
+
end
|
12
|
+
def bar
|
13
|
+
foo
|
14
|
+
end
|
15
|
+
end
|
16
|
+
class RoleB
|
17
|
+
as_role
|
18
|
+
def foo
|
19
|
+
puts "ContextA::RoleB"
|
20
|
+
core.foo()
|
21
|
+
end
|
22
|
+
def bar
|
23
|
+
foo
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class MyObj
|
29
|
+
def foo
|
30
|
+
puts "MyObj"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
o = MyObj.new
|
36
|
+
ca = ContextA.new
|
37
|
+
puts "[bind two roles]"
|
38
|
+
ca.RoleA.bind(o)
|
39
|
+
ca.RoleB.bind(o)
|
40
|
+
# print 3 lines
|
41
|
+
o.bar
|
42
|
+
puts "[unbind one role]"
|
43
|
+
ca.RoleA.unbind(o)
|
44
|
+
# print 2 lines
|
45
|
+
o.bar
|
46
|
+
|
data/examples/person.rb
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
|
2
|
+
require "bunraku"
|
3
|
+
|
4
|
+
class Company
|
5
|
+
as_context
|
6
|
+
|
7
|
+
class Employer
|
8
|
+
as_role
|
9
|
+
def pay(salary)
|
10
|
+
context.Employees.paid(salary)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class Employee
|
15
|
+
as_role
|
16
|
+
def paid(salary)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class Person
|
22
|
+
def initialize
|
23
|
+
@salary = 0
|
24
|
+
end
|
25
|
+
attr :salary
|
26
|
+
def add_salary(salary)
|
27
|
+
@salary += salary
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
tnaka = Person.new
|
32
|
+
sto = Person.new
|
33
|
+
tkahashi = Person.new
|
34
|
+
|
35
|
+
tdai = Company.new
|
36
|
+
tdai.Employee.bind(tnaka) do |b|
|
37
|
+
b.replace_to :paid, :add_salary
|
38
|
+
end
|
39
|
+
|
40
|
+
tdai.Employee.bind(sto) do |b|
|
41
|
+
b.def_method(:paid) do |salary|
|
42
|
+
add_salary(salary)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
tdai.Employer.bind(tkahashi)
|
47
|
+
|
48
|
+
tkahashi.pay 100
|
49
|
+
tkahashi.pay 150
|
50
|
+
p tnaka.salary #=> 250
|
51
|
+
p sto.salary #=> 250
|
52
|
+
|
53
|
+
tdai.Employer.unbind(tkahashi)
|
54
|
+
tdai.Employee.unbind(sto)
|
55
|
+
tdai.Employee.unbind(tnaka)
|
56
|
+
|
57
|
+
begin
|
58
|
+
tkahashi.pay 150
|
59
|
+
rescue => ex
|
60
|
+
p ex #=> NoMethodError
|
61
|
+
end
|
62
|
+
|
63
|
+
begin
|
64
|
+
sto.paid 150
|
65
|
+
rescue => ex
|
66
|
+
p ex #=> NoMethodError
|
67
|
+
end
|
data/examples/person2.rb
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
|
2
|
+
require "bunraku"
|
3
|
+
|
4
|
+
class Company
|
5
|
+
as_context
|
6
|
+
|
7
|
+
class Employer
|
8
|
+
as_role
|
9
|
+
def pay(salary)
|
10
|
+
context.Employees.paid(salary)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class Employee
|
15
|
+
as_role
|
16
|
+
def paid(salary)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class Person
|
22
|
+
def initialize
|
23
|
+
@salary = 0
|
24
|
+
end
|
25
|
+
attr :salary
|
26
|
+
def add_salary(salary)
|
27
|
+
@salary += salary
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
tnaka = Person.new
|
32
|
+
sto = Person.new
|
33
|
+
tkahashi = Person.new
|
34
|
+
|
35
|
+
tdai = Company.new
|
36
|
+
tdai.Employee.bind(tnaka) do |b|
|
37
|
+
b.replace_to :paid, :add_salary
|
38
|
+
end
|
39
|
+
|
40
|
+
tdai.Employee.bind(sto) do |b|
|
41
|
+
b.def_method(:paid) do |salary|
|
42
|
+
add_salary(salary)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
tdai.Employee.bind(tkahashi) do |b|
|
47
|
+
b.def_method(:paid) do |salary|
|
48
|
+
add_salary(salary)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
tdai.Employer.bind(tkahashi)
|
52
|
+
|
53
|
+
tkahashi.pay 100
|
54
|
+
tkahashi.pay 150
|
55
|
+
p tnaka.salary #=> 250
|
56
|
+
p sto.salary #=> 250
|
57
|
+
p tkahashi.salary #=> 250
|
58
|
+
|
59
|
+
tdai.Employee.unbind(tnaka)
|
60
|
+
tdai.Employee.unbind(sto)
|
61
|
+
tdai.Employee.unbind(tkahashi)
|
62
|
+
tdai.Employer.unbind(tkahashi)
|
data/examples/person3.rb
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
|
2
|
+
require "bunraku"
|
3
|
+
|
4
|
+
class Company
|
5
|
+
as_context
|
6
|
+
|
7
|
+
class Employer
|
8
|
+
as_role
|
9
|
+
def pay(salary)
|
10
|
+
context.Employees.paid(salary)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class Employee
|
15
|
+
as_role
|
16
|
+
def paid(salary)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class Person
|
22
|
+
def initialize
|
23
|
+
@salary = 0
|
24
|
+
end
|
25
|
+
attr :salary
|
26
|
+
def add_salary(salary)
|
27
|
+
@salary += salary
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
tnaka = Person.new
|
32
|
+
sto = Person.new
|
33
|
+
tkahashi = Person.new
|
34
|
+
|
35
|
+
|
36
|
+
tdai = Company.new
|
37
|
+
tdai.Employee.bind(tnaka) do |b|
|
38
|
+
b.replace_to :paid, :add_salary
|
39
|
+
end
|
40
|
+
|
41
|
+
tdai.Employee.bind(sto) do |b|
|
42
|
+
b.def_method(:paid) do |salary|
|
43
|
+
add_salary(salary)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
tdai.Employer.bind(tkahashi)
|
48
|
+
|
49
|
+
kdai = Company.new
|
50
|
+
kdai.Employee.bind(tkahashi) do |b|
|
51
|
+
b.replace_to :paid, :add_salary
|
52
|
+
end
|
53
|
+
kdai.Employer.bind(sto)
|
54
|
+
|
55
|
+
|
56
|
+
tkahashi.pay 100
|
57
|
+
tkahashi.pay 150
|
58
|
+
p tnaka.salary #=> 250
|
59
|
+
p sto.salary #=> 250
|
60
|
+
p tkahashi.salary #=> 0
|
61
|
+
sto.pay(100)
|
62
|
+
p tnaka.salary #=> 250
|
63
|
+
p sto.salary #=> 250
|
64
|
+
p tkahashi.salary #=> 100
|
65
|
+
|
66
|
+
|
67
|
+
tdai.Employee.unbind(tnaka)
|
68
|
+
tdai.Employee.unbind(sto)
|
69
|
+
tdai.Employer.unbind(tkahashi)
|
70
|
+
|
71
|
+
kdai.Employee.unbind(tkahashi)
|
72
|
+
kdai.Employer.unbind(sto)
|
@@ -0,0 +1,127 @@
|
|
1
|
+
|
2
|
+
# from
|
3
|
+
# http://www.graco.c.u-tokyo.ac.jp/~tamai/pub/epsilon/examples/company.txt
|
4
|
+
# and
|
5
|
+
# http://www.graco.c.u-tokyo.ac.jp/~tamai/pub/epsilon/examples/rentalshop.txt
|
6
|
+
|
7
|
+
require "bunraku"
|
8
|
+
module RentalShopSystem
|
9
|
+
class Person
|
10
|
+
def initialize(inheritance)
|
11
|
+
@balance = inheritance
|
12
|
+
end
|
13
|
+
def earn(i)
|
14
|
+
@balance += i
|
15
|
+
end
|
16
|
+
def spend(i)
|
17
|
+
@balance -= i
|
18
|
+
end
|
19
|
+
def say
|
20
|
+
puts "Person(balance = " + @balance.to_s + ")"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context :Companey do
|
25
|
+
def initialize(basePay, upPay)
|
26
|
+
@base = basePay
|
27
|
+
@up = upPay
|
28
|
+
end
|
29
|
+
attr :base
|
30
|
+
attr :up
|
31
|
+
|
32
|
+
role :Employee do
|
33
|
+
requires do |req|
|
34
|
+
req.method? :deposit
|
35
|
+
end
|
36
|
+
|
37
|
+
def init_role
|
38
|
+
@salary = context.base
|
39
|
+
end
|
40
|
+
|
41
|
+
def getSalary
|
42
|
+
deposit(@salary)
|
43
|
+
end
|
44
|
+
|
45
|
+
def promoted
|
46
|
+
@salary += context.up
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
role :Employer do
|
51
|
+
def pay
|
52
|
+
context.Employees.getSalary
|
53
|
+
end
|
54
|
+
|
55
|
+
def promote(e)
|
56
|
+
e.promoted
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context :RentalShop do
|
62
|
+
@@max = 5
|
63
|
+
|
64
|
+
def initialize(rentalRate)
|
65
|
+
@rate = rentalRate
|
66
|
+
end
|
67
|
+
attr :rate
|
68
|
+
|
69
|
+
role :Client do
|
70
|
+
requires do |req|
|
71
|
+
req.method? :pay
|
72
|
+
end
|
73
|
+
|
74
|
+
def init_role
|
75
|
+
@count = 0
|
76
|
+
end
|
77
|
+
def rent(n)
|
78
|
+
if @count + n <= @@max
|
79
|
+
pay(n * context.rate)
|
80
|
+
@count += n
|
81
|
+
else
|
82
|
+
m = @@max - n
|
83
|
+
pay(m * context.rate)
|
84
|
+
@count = m
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
|
91
|
+
def self.companeyTodai
|
92
|
+
todai = Companey.new(100, 10)
|
93
|
+
tanaka = Person.new(100)
|
94
|
+
suzuki = Person.new(200)
|
95
|
+
sasaki = Person.new(1000)
|
96
|
+
todai.Employer.bind(sasaki)
|
97
|
+
todai.Employee.bind(tanaka) do |b|
|
98
|
+
b.replace_to :deposit, :earn
|
99
|
+
end
|
100
|
+
todai.Employee.bind(suzuki) do |b|
|
101
|
+
b.replace_to :deposit, :earn
|
102
|
+
end
|
103
|
+
sasaki.promote(tanaka)
|
104
|
+
sasaki.pay
|
105
|
+
|
106
|
+
tanaka.say # => Person(balance = 210) # 100 + (100 + 10)
|
107
|
+
suzuki.say # => Person(balance = 300) # 200 + 100
|
108
|
+
sasaki.say # => Person(balance = 1000) # 1000
|
109
|
+
end
|
110
|
+
|
111
|
+
def self.lifeTanaka
|
112
|
+
todai = Companey.new(100, 10)
|
113
|
+
tanaka = Person.new(100)
|
114
|
+
todai.Employee.bind(tanaka) do |b|
|
115
|
+
b.replace_to :deposit, :earn
|
116
|
+
end
|
117
|
+
tsutaya = RentalShop.new(5)
|
118
|
+
tsutaya.Client.bind(tanaka) do |b|
|
119
|
+
b.replace_to :pay, :spend
|
120
|
+
end
|
121
|
+
tanaka.rent(3)
|
122
|
+
tanaka.say #=> Person(balance = 85) # 100 - 5 * 3
|
123
|
+
end
|
124
|
+
|
125
|
+
companeyTodai
|
126
|
+
lifeTanaka
|
127
|
+
end
|