(fwd) Fw: Self question: interception of assignments

Jecel Assumpcao Jr jecel at merlintec.com
Fri Jul 8 22:11:30 UTC 2005


Here is a reply to an email I received that I thought someone in the
list might have a better solution to than mine.

-- Jecel

----- Original Message ----- 
From: "Jecel Assumpcao Jr"
To: "Ellen Van Paesschen"
Sent: Wednesday, July 06, 2005 5:10 PM
Subject: Re: Self question: interception of assignments


> Ellen,
>
> I am forwarding this to the self-interest mailing list so that more people 
> can look at your problem and perhaps come up with a better solution.
>
>> can you help me out with this: how can I intercept assignments in  Self; 
>> say every time an assignment is performed I want to trigger  another 
>> action.
>
> The normal way it has been done in Self is to hide the real data and 
> assignment slots with a name like rawSomething and then use a regular 
> method to add your action before or after the assignment. You probably 
> have seen things like
>
> ( |  rawSalary <- 0.
>     salary = (rawGrade).
>     salary: v = (rawGrade: v. updateStatistics).
> | )
>
>> Since these method slots contain the assign primitive  I tried wrapping 
>> assignments dynamically but I am stuck due to the nr  of arguments 
>> problem..
>>
>> wrap: sel = ( | m. new. old. sel2 |
>>     m:(reflect: self).
>>
>>     old: ((m at: sel) correspondingAssignmentSlot). "here is now the  <- 
>> slot"
>>     sel2: (old storedName). "the original assign selector"
>
> Please note the word "corresponding". The way Self is implemented the 
> assignment slot must have the same name as the data slot with ':' added to 
> it. A lot of things will stop working if you break this assumption.
>
>>     m at: 'tempy:' PutContents: (reflect: old). "error since wrong  nr of 
>> arguments"
>
> If old is a slot then (reflect: old) is a mirror on the slot and not on 
> the actual method. Such an object can only be placed on a data slot which 
> takes zero arguments. This might be the cause of the error you are seeing.
>
> In theory you could do "old value" instead (if it were a regular method), 
> but in this case that will just get you a mirror on the string '<-' which 
> doesn't help at all.
>
>>     new: ('| :arg1 | triggerAction . tempy: arg1') parseObjectBody.
>>
>>     m at: sel2 PutContents: new.
>> )
>> Can I avoid this or is there a more simple way to intercept assignments?
>
> The most recent version of Self (4.2.1) allows you to store method objects 
> in slots, but that is enabled by default and I don't see a simple way in 
> which that would help with your problem. I think the only way to do it is 
> patching the object like you are doing. You might want to check out the 
> method 'changeSlotInObjectTo:' in "traits slots plain" or something 
> similar to rename the original slots adding 'raw' to their names and then 
> creating two additional methods.
>
> You might find a related discussion from 1994 interesting:
>
> http://www.merlintec.com/old-self-interest/msg00520.html
>
> -- Jecel

Here was the reply:

thanks for the response - I didn't find a straightforward solution
and since we were limited by a paper deadline, I implemented some
kind of assignment "shadowing".  A new child object is created that
overrides the assignment with some action to be triggered and then a
resend to the original assignment. All references to the object
containing the original assignment are then set to the new child
object..



More information about the Self-interest mailing list