cosell 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/History.txt +3 -0
- data/README.rdoc +190 -0
- data/Rakefile +65 -0
- data/cosell.gemspec +65 -0
- data/example/basic_example.rb +99 -0
- data/example/cat_whisperer.rb +87 -0
- data/lib/cosell.rb +48 -0
- data/lib/cosell/announcer.rb +236 -0
- data/lib/cosell/monkey.rb +32 -0
- data/spec/cosell_spec.rb +179 -0
- data/spec/spec_helper.rb +14 -0
- data/tasks/ann.rake +80 -0
- data/tasks/bones.rake +20 -0
- data/tasks/gem.rake +201 -0
- data/tasks/git.rake +40 -0
- data/tasks/notes.rake +27 -0
- data/tasks/post_load.rake +34 -0
- data/tasks/rdoc.rake +51 -0
- data/tasks/rubyforge.rake +55 -0
- data/tasks/setup.rb +292 -0
- data/tasks/spec.rake +54 -0
- data/tasks/svn.rake +47 -0
- data/tasks/test.rake +40 -0
- data/tasks/zentest.rake +36 -0
- metadata +126 -0
data/.gitignore
ADDED
data/History.txt
ADDED
data/README.rdoc
ADDED
@@ -0,0 +1,190 @@
|
|
1
|
+
cosell
|
2
|
+
|
3
|
+
by {Steven Swerling}[http://tab-a.slot-z.net]
|
4
|
+
|
5
|
+
{rdoc}[http://tab-a.slot-z.net] | {github}[http://www.github.com/swerling/cosell]
|
6
|
+
|
7
|
+
|
8
|
+
== DESCRIPTION:
|
9
|
+
|
10
|
+
Cosell is a minimal implementation of the 'Announcements' observer
|
11
|
+
framework, originally introduced in VisualWorks Smalltalk as a
|
12
|
+
replacement for 'triggerEvent' style of event notification. Instead of
|
13
|
+
triggering events identified by symbols, the events are first class
|
14
|
+
objects. For rationale, please see the original blog posting by Vassili
|
15
|
+
Bykov (refs below).
|
16
|
+
|
17
|
+
*Lineage*
|
18
|
+
|
19
|
+
This implementation is loosely based on Lukas Renggli's tweak of Colin Putney's
|
20
|
+
Squeak implementation of Vassili Bykov's Announcements framework for
|
21
|
+
VisualWorks Smalltalk. (Specifically Announcements-lr.13.mcz was used as
|
22
|
+
a reference.)
|
23
|
+
|
24
|
+
Liberties where taken during the port. In particular, the Announcer class
|
25
|
+
in the Smalltalk version is implemented here as a ruby module which can be
|
26
|
+
mixed into any object. Also, in this implementation any object (or class)
|
27
|
+
can serve as an announcement, so no Announcement class is implemented.
|
28
|
+
|
29
|
+
The ability to queue announcements in the background is built into cosell.
|
30
|
+
|
31
|
+
<b>The Name 'Cosell'</b>
|
32
|
+
|
33
|
+
I chose the name 'Cosell' because
|
34
|
+
|
35
|
+
a. Howard Cosell is an iconic event announcer
|
36
|
+
b. Googling for 'Ruby Announcements', 'Ruby Event Announcements', etc., produced scads of results about ruby meetups, conferences, and the like. So I went with something a bit cryptic but hopefully a little more searchable.
|
37
|
+
|
38
|
+
*See*
|
39
|
+
|
40
|
+
* {Original blog posting describing Announcments by Vassili Bykov}[http://www.cincomsmalltalk.com/userblogs/vbykov/blogView?entry=3310034894]
|
41
|
+
* {More info on the Announcements Framework}[http://wiki.squeak.org/squeak/5734]
|
42
|
+
|
43
|
+
== FEATURE
|
44
|
+
|
45
|
+
* Announcements-style event observer framework
|
46
|
+
* Synchronous announcements and asynchronous announcements (using a background thread with a queue)
|
47
|
+
|
48
|
+
== PROBLEMS
|
49
|
+
|
50
|
+
* None known. Should work in ruby 1.8 and 1.9.
|
51
|
+
|
52
|
+
== SYNOPSIS:
|
53
|
+
|
54
|
+
|
55
|
+
(this example is in the [gem]/example/basic_example.rb file)
|
56
|
+
|
57
|
+
#
|
58
|
+
# Will produce the following output:
|
59
|
+
#
|
60
|
+
# And now a word from our sponsor: 'the'
|
61
|
+
# End of round 1
|
62
|
+
# End of round 2
|
63
|
+
# End of round 3
|
64
|
+
# End of round 4
|
65
|
+
# End of round 5
|
66
|
+
# End of round 6
|
67
|
+
# End of round 7
|
68
|
+
# End of round 8
|
69
|
+
# End of round 9
|
70
|
+
# End of round 10
|
71
|
+
# End of round 11
|
72
|
+
# End of round 12
|
73
|
+
# End of round 13
|
74
|
+
# End of round 14
|
75
|
+
# TKO!
|
76
|
+
|
77
|
+
require 'rubygems'
|
78
|
+
require 'cosell'
|
79
|
+
|
80
|
+
# An announcer
|
81
|
+
class Howard
|
82
|
+
include Cosell
|
83
|
+
end
|
84
|
+
|
85
|
+
# a receiver of the announcements
|
86
|
+
class Television
|
87
|
+
def show(ann, opts={})
|
88
|
+
puts ann.to_s(opts)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
# Some announcements
|
93
|
+
class Announcement
|
94
|
+
def to_s(opts={})
|
95
|
+
self.class.to_s + '!'
|
96
|
+
end
|
97
|
+
end
|
98
|
+
class WordFromOurSponsor < Announcement
|
99
|
+
attr_accessor :word
|
100
|
+
def to_s(opts={})
|
101
|
+
"And now a word from our sponsor: '#{word}'"
|
102
|
+
end
|
103
|
+
end
|
104
|
+
class EndOfRound < Announcement
|
105
|
+
def to_s(opts={})
|
106
|
+
"End of round #{opts[:round]}"
|
107
|
+
end
|
108
|
+
end
|
109
|
+
class KnockOut < Announcement; end
|
110
|
+
class TKO < KnockOut; end
|
111
|
+
|
112
|
+
|
113
|
+
# ------- Start announcing -------
|
114
|
+
|
115
|
+
# Create an announcer, and a subscriber
|
116
|
+
round = 1
|
117
|
+
howard = Howard.new
|
118
|
+
tv = Television.new
|
119
|
+
howard.when_announcing(WordFromOurSponsor, KnockOut) { |ann| tv.show(ann) }
|
120
|
+
|
121
|
+
# Make an announcement
|
122
|
+
announcement = WordFromOurSponsor.new
|
123
|
+
announcement.word = 'the'
|
124
|
+
howard.announce(announcement)
|
125
|
+
# => And know a word from our sponsors: 'the'
|
126
|
+
|
127
|
+
# Make another announcement
|
128
|
+
howard.announce(EndOfRound)
|
129
|
+
# => nothing, you haven't subscribed yet to EndOfRound. Tree fell, nobody heard. Didn't happen.
|
130
|
+
|
131
|
+
# Create a second subscription
|
132
|
+
eor_subscription = lambda do |ann|
|
133
|
+
tv.show(ann, :round => round)
|
134
|
+
round += 1
|
135
|
+
end
|
136
|
+
howard.when_announcing(EndOfRound, &eor_subscription)
|
137
|
+
|
138
|
+
# Tell the announcer to use a background announcments queue
|
139
|
+
# Only allow the announcer to broadcast 5 announcments at a time
|
140
|
+
# before going to sleep for 0.05 seconds
|
141
|
+
howard.queue_announcements!(:sleep_time => 0.05, :announcements_per_cycle => 5)
|
142
|
+
|
143
|
+
# Start making announcments (they will be queueud in the background)
|
144
|
+
14.times {howard.announce(EndOfRound)}
|
145
|
+
|
146
|
+
sleep 0.05 # announcements for the first 5 rounds appear
|
147
|
+
sleep 0.05 # announcements for the next 5 rounds
|
148
|
+
sleep 0.05 # announcements for end of the next 4 rounds (there is not 15th round
|
149
|
+
sleep 0.05 # no announcements, all the announcements have been announced
|
150
|
+
|
151
|
+
# queue the final announcment
|
152
|
+
howard.announce(TKO)
|
153
|
+
# => TKO!
|
154
|
+
|
155
|
+
sleep 0.05 # the TKO is broadcast
|
156
|
+
|
157
|
+
== REQUIREMENTS:
|
158
|
+
|
159
|
+
* ruby, rubygems
|
160
|
+
|
161
|
+
== INSTALL:
|
162
|
+
|
163
|
+
|
164
|
+
gem install swerling-cosell --source http://gems.github.com
|
165
|
+
|
166
|
+
|
167
|
+
== LICENSE:
|
168
|
+
|
169
|
+
(The MIT License)
|
170
|
+
|
171
|
+
Copyright (c) 2009
|
172
|
+
|
173
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
174
|
+
a copy of this software and associated documentation files (the
|
175
|
+
'Software'), to deal in the Software without restriction, including
|
176
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
177
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
178
|
+
permit persons to whom the Software is furnished to do so, subject to
|
179
|
+
the following conditions:
|
180
|
+
|
181
|
+
The above copyright notice and this permission notice shall be
|
182
|
+
included in all copies or substantial portions of the Software.
|
183
|
+
|
184
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
185
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
186
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
187
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
188
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
189
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
190
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
# Look in the tasks/setup.rb file for the various options that can be
|
2
|
+
# configured in this Rakefile. The .rake files in the tasks directory
|
3
|
+
# are where the options are used.
|
4
|
+
|
5
|
+
begin
|
6
|
+
require 'bones'
|
7
|
+
Bones.setup
|
8
|
+
rescue LoadError
|
9
|
+
begin
|
10
|
+
load 'tasks/setup.rb'
|
11
|
+
rescue LoadError
|
12
|
+
raise RuntimeError, '### please install the "bones" gem ###'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
ensure_in_path 'lib'
|
17
|
+
require 'cosell'
|
18
|
+
|
19
|
+
task :default => 'spec:run'
|
20
|
+
|
21
|
+
PROJ.name = 'cosell'
|
22
|
+
PROJ.authors = 'Steven Swerling'
|
23
|
+
PROJ.email = 'sswerling@yahoo.com'
|
24
|
+
PROJ.url = 'http://github.com/swerling/TODO'
|
25
|
+
PROJ.version = Cosell::VERSION
|
26
|
+
PROJ.rubyforge.name = 'cosell'
|
27
|
+
PROJ.readme_file = 'README.rdoc'
|
28
|
+
|
29
|
+
PROJ.spec.opts << '--color'
|
30
|
+
|
31
|
+
PROJ.rdoc.opts = ["--inline-source", "-o rdoc", "--format=html", "-T hanna"]
|
32
|
+
|
33
|
+
|
34
|
+
|
35
|
+
require 'fileutils'
|
36
|
+
def this_dir; File.join(File.dirname(__FILE__)); end
|
37
|
+
def doc_dir; File.join(this_dir, 'rdoc'); end
|
38
|
+
def tab_a_doc_dir; File.join(this_dir, '../tab-a/public/cosell/rdoc'); end
|
39
|
+
task :myclobber => [:clobber] do
|
40
|
+
mydir = File.join(File.dirname(__FILE__))
|
41
|
+
sh "rm -rf #{File.join(mydir, 'pkg')}"
|
42
|
+
sh "rm -rf #{File.join(mydir, 'doc')}"
|
43
|
+
sh "rm -rf #{File.join(mydir, 'rdoc')}"
|
44
|
+
sh "rm -rf #{File.join(mydir, 'ext/*.log')}"
|
45
|
+
sh "rm -rf #{File.join(mydir, 'ext/*.o')}"
|
46
|
+
sh "rm -rf #{File.join(mydir, 'ext/*.so')}"
|
47
|
+
sh "rm -rf #{File.join(mydir, 'ext/Makefile')}"
|
48
|
+
sh "rm -rf #{File.join(mydir, 'ext/Makefile')}"
|
49
|
+
end
|
50
|
+
task :mypackage => [:myclobber] do
|
51
|
+
Rake::Task['gem:package'].invoke
|
52
|
+
end
|
53
|
+
task :mydoc => [:myclobber] do
|
54
|
+
FileUtils.rm_f doc_dir()
|
55
|
+
sh "cd #{this_dir()} && rdoc -o rdoc --inline-source --format=html -T hanna README.rdoc lib/**/*.rb"
|
56
|
+
end
|
57
|
+
task :taba => [:mydoc] do
|
58
|
+
this_dir = File.join(File.dirname(__FILE__))
|
59
|
+
FileUtils.rm_rf tab_a_doc_dir
|
60
|
+
FileUtils.cp_r doc_dir, tab_a_doc_dir
|
61
|
+
end
|
62
|
+
|
63
|
+
task :mygemspec => [:myclobber] do
|
64
|
+
Rake::Task['gem:spec'].invoke
|
65
|
+
end
|
data/cosell.gemspec
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{cosell}
|
5
|
+
s.version = "0.0.2"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Steven Swerling"]
|
9
|
+
s.date = %q{2009-08-09}
|
10
|
+
s.description = %q{Cosell is a minimal implementation of the 'Announcements' observer
|
11
|
+
framework, originally introduced in VisualWorks Smalltalk as a
|
12
|
+
replacement for 'triggerEvent' style of event notification. Instead of
|
13
|
+
triggering events identified by symbols, the events are first class
|
14
|
+
objects. For rationale, please see the original blog posting by Vassili
|
15
|
+
Bykov (refs below).
|
16
|
+
|
17
|
+
*Lineage*
|
18
|
+
|
19
|
+
This implementation is loosely based on Lukas Renggli's tweak of Colin Putney's
|
20
|
+
Squeak implementation of Vassili Bykov's Announcements framework for
|
21
|
+
VisualWorks Smalltalk. (Specifically Announcements-lr.13.mcz was used as
|
22
|
+
a reference.)
|
23
|
+
|
24
|
+
Liberties where taken during the port. In particular, the Announcer class
|
25
|
+
in the Smalltalk version is implemented here as a ruby module which can be
|
26
|
+
mixed into any object. Also, in this implementation any object (or class)
|
27
|
+
can serve as an announcement, so no Announcement class is implemented.
|
28
|
+
|
29
|
+
The ability to queue announcements in the background is built into cosell.
|
30
|
+
|
31
|
+
<b>The Name 'Cosell'</b>
|
32
|
+
|
33
|
+
I chose the name 'Cosell' because
|
34
|
+
|
35
|
+
a. Howard Cosell is an iconic event announcer
|
36
|
+
b. Googling for 'Ruby Announcements', 'Ruby Event Announcements', etc., produced scads of results about ruby meetups, conferences, and the like. So I went with something a bit cryptic but hopefully a little more searchable.
|
37
|
+
|
38
|
+
*See*
|
39
|
+
|
40
|
+
* {Original blog posting describing Announcments by Vassili Bykov}[http://www.cincomsmalltalk.com/userblogs/vbykov/blogView?entry=3310034894]
|
41
|
+
* {More info on the Announcements Framework}[http://wiki.squeak.org/squeak/5734]}
|
42
|
+
s.email = %q{sswerling@yahoo.com}
|
43
|
+
s.extra_rdoc_files = ["History.txt", "README.rdoc"]
|
44
|
+
s.files = [".gitignore", "History.txt", "README.rdoc", "Rakefile", "cosell.gemspec", "example/basic_example.rb", "example/cat_whisperer.rb", "lib/cosell.rb", "lib/cosell/announcer.rb", "lib/cosell/monkey.rb", "spec/cosell_spec.rb", "spec/spec_helper.rb"]
|
45
|
+
s.has_rdoc = true
|
46
|
+
s.homepage = %q{http://github.com/swerling/TODO}
|
47
|
+
s.rdoc_options = ["--inline-source", "-o rdoc", "--format=html", "-T hanna", "--main", "README.rdoc"]
|
48
|
+
s.require_paths = ["lib"]
|
49
|
+
s.rubyforge_project = %q{cosell}
|
50
|
+
s.rubygems_version = %q{1.3.2}
|
51
|
+
s.summary = %q{Cosell is a minimal implementation of the 'Announcements' observer framework, originally introduced in VisualWorks Smalltalk as a replacement for 'triggerEvent' style of event notification}
|
52
|
+
|
53
|
+
if s.respond_to? :specification_version then
|
54
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
55
|
+
s.specification_version = 3
|
56
|
+
|
57
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
58
|
+
s.add_development_dependency(%q<bones>, [">= 2.5.1"])
|
59
|
+
else
|
60
|
+
s.add_dependency(%q<bones>, [">= 2.5.1"])
|
61
|
+
end
|
62
|
+
else
|
63
|
+
s.add_dependency(%q<bones>, [">= 2.5.1"])
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
#
|
2
|
+
# Will produce the following output:
|
3
|
+
#
|
4
|
+
# And now a word from our sponsor: 'the'
|
5
|
+
# End of round 1
|
6
|
+
# End of round 2
|
7
|
+
# End of round 3
|
8
|
+
# End of round 4
|
9
|
+
# End of round 5
|
10
|
+
# End of round 6
|
11
|
+
# End of round 7
|
12
|
+
# End of round 8
|
13
|
+
# End of round 9
|
14
|
+
# End of round 10
|
15
|
+
# End of round 11
|
16
|
+
# End of round 12
|
17
|
+
# End of round 13
|
18
|
+
# End of round 14
|
19
|
+
# TKO!
|
20
|
+
|
21
|
+
require 'rubygems'
|
22
|
+
require 'cosell'
|
23
|
+
|
24
|
+
# An announcer
|
25
|
+
class Howard
|
26
|
+
include Cosell
|
27
|
+
end
|
28
|
+
|
29
|
+
# a receiver of the announcements
|
30
|
+
class Television
|
31
|
+
def show(ann, opts={})
|
32
|
+
puts ann.to_s(opts)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# Some announcements
|
37
|
+
class Announcement
|
38
|
+
def to_s(opts={})
|
39
|
+
self.class.to_s + '!'
|
40
|
+
end
|
41
|
+
end
|
42
|
+
class WordFromOurSponsor < Announcement
|
43
|
+
attr_accessor :word
|
44
|
+
def to_s(opts={})
|
45
|
+
"And now a word from our sponsor: '#{word}'"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
class EndOfRound < Announcement
|
49
|
+
def to_s(opts={})
|
50
|
+
"End of round #{opts[:round]}"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
class KnockOut < Announcement; end
|
54
|
+
class TKO < KnockOut; end
|
55
|
+
|
56
|
+
|
57
|
+
# ------- Start announcing -------
|
58
|
+
|
59
|
+
# Create an announcer, and a subscriber
|
60
|
+
round = 1
|
61
|
+
howard = Howard.new
|
62
|
+
tv = Television.new
|
63
|
+
howard.when_announcing(WordFromOurSponsor, KnockOut) { |ann| tv.show(ann) }
|
64
|
+
|
65
|
+
# Make an announcement
|
66
|
+
announcement = WordFromOurSponsor.new
|
67
|
+
announcement.word = 'the'
|
68
|
+
howard.announce(announcement)
|
69
|
+
# => And know a word from our sponsors: 'the'
|
70
|
+
|
71
|
+
# Make another announcement
|
72
|
+
howard.announce(EndOfRound)
|
73
|
+
# => nothing, you haven't subscribed yet to EndOfRound. Tree fell, nobody heard. Didn't happen.
|
74
|
+
|
75
|
+
# Create a second subscription
|
76
|
+
eor_subscription = lambda do |ann|
|
77
|
+
tv.show(ann, :round => round)
|
78
|
+
round += 1
|
79
|
+
end
|
80
|
+
howard.when_announcing(EndOfRound, &eor_subscription)
|
81
|
+
|
82
|
+
# Tell the announcer to use a background announcments queue
|
83
|
+
# Only allow the announcer to broadcast 5 announcments at a time
|
84
|
+
# before going to sleep for 0.05 seconds
|
85
|
+
howard.queue_announcements!(:sleep_time => 0.05, :announcements_per_cycle => 5)
|
86
|
+
|
87
|
+
# Start making announcments (they will be queueud in the background)
|
88
|
+
14.times {howard.announce(EndOfRound)}
|
89
|
+
|
90
|
+
sleep 0.05 # announcements for the first 5 rounds appear
|
91
|
+
sleep 0.05 # announcements for the next 5 rounds
|
92
|
+
sleep 0.05 # announcements for end of the next 4 rounds (there is not 15th round
|
93
|
+
sleep 0.05 # no announcements, all the announcements have been announced
|
94
|
+
|
95
|
+
# queue the final announcment
|
96
|
+
howard.announce(TKO)
|
97
|
+
# => TKO!
|
98
|
+
|
99
|
+
sleep 0.05 # the TKO is broadcast
|
@@ -0,0 +1,87 @@
|
|
1
|
+
#
|
2
|
+
# Sits by window, talks to cats
|
3
|
+
#
|
4
|
+
class CatWhisperer
|
5
|
+
include Cosell::Announcer
|
6
|
+
end
|
7
|
+
|
8
|
+
#
|
9
|
+
# events that occur in the home
|
10
|
+
#
|
11
|
+
class SomeoneEnteringHome
|
12
|
+
attr_accessor :who_is_entering
|
13
|
+
end
|
14
|
+
class OwnerEnteringHome < SomeoneEnteringHome; end
|
15
|
+
class BurglerEnteringHome < SomeoneEnteringHome; end
|
16
|
+
class DogEnteringHome < SomeoneEnteringHome; end
|
17
|
+
class BirdEnteringHome < SomeoneEnteringHome; end
|
18
|
+
|
19
|
+
#
|
20
|
+
# participants
|
21
|
+
#
|
22
|
+
class Cat
|
23
|
+
end
|
24
|
+
class NormalSizedCat < Cat
|
25
|
+
def deal_with_dog(dog)
|
26
|
+
if dog.running_at_cat?(self)
|
27
|
+
puts "run to bookshelf; climb bookshelf; feign indifference"
|
28
|
+
else
|
29
|
+
puts "feign indifference; saunter to bookshelf; climb bookshelf; feign indifference"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
def deal_with_burgler(burgler)
|
33
|
+
puts "feign indifference"
|
34
|
+
end
|
35
|
+
def deal_with_owner(owner)
|
36
|
+
puts "feign indifference while slowly sauntering towards owner; " \
|
37
|
+
+ "nuzzle owner; receive affection; try to feign indifference; break down and start purring"
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
class ReallyBigCat < Cat
|
43
|
+
def eat(who)
|
44
|
+
puts "Really big cat eats #{who}"
|
45
|
+
end
|
46
|
+
def deal_with_burgler(burgler)
|
47
|
+
eat('burgler')
|
48
|
+
end
|
49
|
+
def deal_with_owner(owner)
|
50
|
+
eat('owner')
|
51
|
+
end
|
52
|
+
def deal_with_dog(owner)
|
53
|
+
eat('dog')
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
cat_whisperer = CatWhisperer.new
|
58
|
+
really_big_cat = ReallyBigCat.new
|
59
|
+
regular_cat = NormalSizedCat.new
|
60
|
+
|
61
|
+
#
|
62
|
+
# wire up events
|
63
|
+
#
|
64
|
+
cat_whisperer.when_announcing(DogEnteringHome) do |event|
|
65
|
+
cat.deal_with_dog(event.who_is_entering)
|
66
|
+
rally_big_cat.deal_with_dog(event.who_is_entering)
|
67
|
+
end
|
68
|
+
cat_whisperer.when_announcing(DogEnteringHome, :send => |event|
|
69
|
+
cat.deal_with_dog(event.who_is_entering)
|
70
|
+
rally_big_cat.deal_with_dog(event.who_is_entering)
|
71
|
+
end
|
72
|
+
|
73
|
+
cat_whisperer.when_announcing(OwnerEnteringHome) do |event|
|
74
|
+
cat.deal_with_person(dog_entering_event.who_is_entering)
|
75
|
+
rally_big_cat.deal_with_dog(dog_entering_event.who_is_entering)
|
76
|
+
end
|
77
|
+
|
78
|
+
cat_whisperer.when_announcing(BurglerEnteringHome) do |event|
|
79
|
+
cat.deal_with_person(event.who_is_entering)
|
80
|
+
rally_big_cat.deal_with_dog(event.who_is_entering)
|
81
|
+
end
|
82
|
+
|
83
|
+
#
|
84
|
+
# Mayhem ensues
|
85
|
+
#
|
86
|
+
cat_whisperer.announce(OwnerEnteringHome.new)
|
87
|
+
# =>
|