Thanks again everyone for providing those suggestions on learning
Smalltalk. I took the advice and picked up Smalltalk Objects and
Design by Chamond Liu. I'm about half way through it now, and
plowing through the material on MVC, which I'll see if I can translate
in MVP design.
One thing that I have not been able to inspect, though, involves the
Dependency mechanism which Models employ to notify Views of updates.
In pp.120-121, the book gives an example of how to implement
First I added a method called update to the existing Integer class:
show: 'I am ', self printString.
Then in the workspace, I add dependents for notification:
x := Integer new.
x addDependent 17.
x addDependent 12.
Dependents inspect. "This does not work"
x broadcast: #update. "Nonetheless the broadcast works"
Since there is no Dependents class in Dolphin, the book also suggests
inspecting the object's classPool instead:
x class classPool inspect. "I'm able to see the classPool in the
When I evaluate the above line, an Inspector window pops up with a
long list of classPool entries, but I can't locate the relevant key
and collection to check to see if the 2 numbers 17, 12 have been added
to some Dependents' list.
Searching through some other documentation, I tried to inspect
x class classPool at: 'DependentsFields'
but that didn't work either.
Can someone tell me where the Dependents list is located in a class,
where the notifcation mechanism checks to send its broadcast?
The book suggests though that the above approach is too broad and too
visible, so VAST for example provides AbtObservableObject which stores
dependents in eventDependents in order to provide multicasts of
specific events. Does Dolphin have something similar to this?
then you'll see how Dolphin uses a weak collection held in a class variable of
Object (_DependentsRegister) to implement the mapping between the Observers and
the Observed. The class variable is shared with all the subclasses of Object,
so you won't find it on Integer. Try
Object classPool "inspectIt"
Object classPool at: #_DependentsRegister
The second point is that when you are experimenting with this, you'd be better
off using Objects (or Stings or something) that you've created explicitly with
a #new. That way you have a precise notion of *which* object you are playing
with. (Small)Integers are not really created and destroyed in the same way as
other objects, so questions of identity can be more confusing that you need.
Also the dependency mechanism is usually used to notify listeners of some
change to an object's state, and Integers never change...
Lastly, nobody uses the dependency mechanism in Dolphin very much. Its there
for portability, but most Dolphin code used the similar, but more flexible,
event mechanism instead (not to be confused with Windows events). For
instance, doing a
someObject trigger: #anEvent
broadcasts the event #anEvent to each Observer of anObject.
You use #when:send:to: (and friends) to register an object (usually 'self') as
an Observer; for instance
someObject when: #anEvent send: #handleAnEvent to: anotherObject
will arrange that when #anEvent is triggered off someObject, the #handleAnEvent
method of anotherObject will be invoked.
> One thing that I have not been able to inspect, though, involves the
> Dependency mechanism which Models employ to notify Views of updates.
The Dependency mechanism is now considered to be somewhat "old hat".
Dolphin's MVP makes use of a different mechanism (events) and the
dependency framework is really only present for backward compatibility.
> x := Integer new.
? That shouldn't work and, as expected, I get a walkback. Integers are
immutable and you can't create a new one.
> Dependents inspect. "This does not work"
You will have to reverse the question and ask the object for it's
x := Ball new.
y := Ball new.
x addDependent: y.
> x broadcast: #update. "Nonetheless the broadcast works"
Add #update to Ball and that will still work
Dolphin holds it's dependency information in a ClassVariable belonging
to the Object class named "_DependentsRegister". The easiest way to
track down this sort of information is trace through the operation of a
selector that you know works (#addDependent: is a good one in this case)
and see what it does. That should point you at the #getDependents and
#setDependent methods and that gives you the _DependentsRegister class
variable. Note that #getDependents and #setDependents are marked as
private which tells you that you shouldn't rely on their presence in
future versions and, more importantly, shouldn't rely on their internal
operation. _DependentsRegister is used in the current implementation but
that may change in the future.