[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
|