[Q] on when:send:to:

John W. Sarkela sarkela at sbcglobal.net
Tue May 27 23:00:15 UTC 2003


Your code is working, and no, it should not print anything to the 
transcript. Let's take a step back and understand better the theory and 
practice of using these kinds of events. Subsequently, I shall explain 
what is occurring in your sample code and why the correct behavior 
should not print anything.

Think of #when:send:to: as a kind of broadcast communication. A typical 
scenario would have a domain object that may transition through a 
number of states of interest to zero or more observers. When one of 
these interesting events occurs, it triggers that event and all 
registered listeners will receive a notification in the form of a 
message send that they themselves have registered. This is a form of 
the Observer pattern, but the folks at KSC liked to call it the SASE 
pattern (Self addressed stamped envelope).

Thus, the domain object is a transmitter of events. Various observers 
interested in that event from that particular object "tune in" to that 
station using #when:send:to:. Sources of events should inherit from 
EventManager if at all possible.

Example:  file in the code in the attached source file

note: The domain object is defined by the class, EventfulDomainObject.
	The observer object is defined by the class, EventObserverObject.

Open a Transcript window and then evaluate the following expressions 
one at a time.
---------- snip workspace expressions ----------
d1 := EventfulDomainObject new.
d2 := EventfulDomainObject new.
o1 := EventObserverObject new.

d1 user: 'Fred Flintstone'.	"no changes in transcript"

o1 observeUserChangesIn: d1.
d1 user: 'Fred Flintstone'. 	"transcript shows, User: Fred Flintstone"
d2 user: 'Barney Rubble'.	"no changes in transcript"

o1 observeUserChangesIn: d2.
d1 user: 'Fred Flintstone'. 	"transcript shows, User: Fred Flintstone"
d2 user: 'Betty Rubble'.		"transcript shows, User: Betty Rubble"

o1 ignoreUserChangesIn: d1.
d1 user: 'Fred Flintstone'. 	"no changes in transcript"
d2 user: 'Betty Rubble'.		"transcript shows, User: Betty Rubble"

o1 observeFortuneChangesIn: d1.
o1 observeFortuneChangesIn: d2.
d1 fortune: 'minds are like parachutes, they work best when open'. 
"transcript shows fortune"
d2 fortune: 'the best things in life, are not things'. "transcript 
shows fortune"

o1 ignoreFortuneChangesIn: d1.
d1 fortune: 'a light heart makes for an easy mind'. "no change in 
transcript"
d2 fortune: 'a light heart makes for an easy mind'. "transcript shows 
fortune"
--------- snip end of workspace expressions -----------

d1 and d2 are references to objects that may trigger the events 
#userChanged: and #fortuneChanged:. The first time #user: is sent to 
d1, it triggers it's #userChanged:. But since no one is listening, 
nothing happens.

when we send the message #observeUserChangesIn: to the observer, o1, 
with the first domain object, d1 as its argument, we are registering 
the intent to listen to all user events broadcast by domain object, d1. 
Thus, we see o1 react to user changes in d1, but it ignores user 
changes in d2.
That is, of course, until we register our intent to listen to d2 user 
changes as well. The explanation for the rest of the workspace code is 
left as an exercise for the reader.

Look to the end for the explanation of what is happening in your sample 
code.

On Tuesday, May 27, 2003, at 02:02 PM, Ingo Hohmann wrote:

> OK, this ia the last question for today, I promise!
>
> I found the reference to when:send:to: on the SWiki, now I tried it 
> with two classes ...
>
> class RecieveEvent:
>
> initalize
> 	self when: #variableChanged send: #variableChanged to: self
>
> variableChanged	
> 	Transcript show: 'variabel has changed'
>
>
> class TriggerEvent:
>
> variable: aVal
> 	variable _ aVal.
> 	self triggerEvent: #variableChanged.
> 	^ variable
>
>
> And in the WorkSpace:
>
> t1 _ RecieveEvent new.

Here you have created an instance of ReceiveEvent which in its 
initialization declares the intention of sending itself the message, 
#variableChanged, whenever it triggers the event, #variableChanged.
Since there is no code within ReceiveEvent to trigger that event, it is 
unlikely that the method #variableChanged will ever be invoked.

> t2 _ TriggerEvent new.

Here you create a domain object that should be a subclass of 
EventManager.

> t2 variable: 11.
>

Here you send the message, #variable:, to t2 which in turn triggers the 
event, #variableChanged. Unfortunately, no one is listening to object 
t2, so no one responds to its triggering of that event.
What do you suppose would happen if you evaluated the following 
expression in that workspace?

t1 triggerEvent: #variableChanged

>
> Shouldn't this print the message? I searched for when:send:for: 
> senders and only found about 7 in my image (3.5) am I missing 
> something?
>

When an observer wants to listen to events, it must
	1. identify to which object it is listening (the receiver of 
#when:send:to: )
	2. identify the particular event (the argument for when: )
	3. identify the particular message to send (the argument to send: )
	4. identify the receiver of the notification method ( the argument to 
to: )

what you missed was that your receiver was listening only to itself (as 
established in its initialize method) so that when the t2 object 
triggered its event, no one was registered as a listener.

Cheers,
:-}> John Sarkela

>
> Kind regards,
>
> Ingo
>
>
>
> And thanks for all the answers!
>
>



More information about the Squeak-dev mailing list