Steven: Oh! I was unaware of these methods under reflection protocol! I manage to make it work, and it is simply AWESOME!! :) Marcus: I wanted to intercept the store generally, with any kind of slot, kind of an AOP aproach. I did this: | slotLink | slotLink := (MetaLink new metaObject: [Transcript show: 'ihaaaa!!!!']; selector: #value; arguments: #(); control: #before). TestObject link: slotLink toSlotNamed: #b option: #write. And it worked like a charm! By you explanation, this would lead to some performance penality, but it seems a really powerfull mechanism to me, and it's performance should be similar to that of extending a Slot, no? On Thu, Apr 4, 2019 at 5:04 AM Marcus Denker <marcus.denker@inria.fr> wrote:
On 3 Apr 2019, at 15:57, Vitor Medina Cruz <vitormcruz@gmail.com> wrote:
Hello,
Is it possible to intercept a slot store? I tried with a before metalink into #write:to selector, but it don't seems to work. Should I use another selector?
The #write:to: method is the reflective read method that implements read on the level of the variable. If you subclass class Slot, you can make you own kind of Variables by just overriding #write:to and read:
But of course compiling every read by calling a method would be very slow.
Therefore, one can override emitStore: and emitValue: to instead emit faster code by telling the compiler exactly what bytecode to generate for read and write. This makes it much faster, but at the expense that the reflective methods are not called anymore.
(It would be nicer if we would inline the read: code automatically, but that has its own set of problems)
I would like to experiment with ivar change notification, but I don't know what is the better approach.
What you could do is to make your own subclass to experiment. IndexedSlot is the superclass of the normal instancevariables, but without the optimised code generation. So it is the perfect superclass to experiment:
IndexedSlot subclass: #MyTestSlot instanceVariableNames: '' classVariableNames: '' package: 'Slot-Core-Variablesâ
now Implement
read: anObject Transcript show: 'reading ', self name. super read: anObject.
Now we can make a class that uses it:
Object subclass: #MyClass slots: { #ivar => MyTestSlot } classVariables: { } package: 'Slot-Core-Variablesâ
and add a simple method reading the variable:
ivar ^ivar
If you now execute "MyClass new ivarâ and you will see the output on the Transcript.
Marcus