Dear all, I am trying to understand better reflection in Smalltalk. I am using the latest version of Squeak (v4.3). I want to intercept every message sent to instances of one of my classes. I assumed that I could override the method `ProtoObject>>withArgs:executeMethod` but Stéphane (Ducasse) explained me that for performance reason, this method is not used (this is my own summary of his answer). Which method should I override / how could intercept sent messages? Here is the code of my attempt: Object subclass: #C instanceVariableNames: 'i' classVariableNames: '' poolDictionaries: '' category: 'CSE3009'. C class compile: 'newWithi: anInt ^(self new) i: anInt ; yourself.'. C compile: 'withArgs: someArgs executeMethod: aMethod Transcript show: ''Caught: ''. ^ super withArgs: someArgs executeMethod aMethod.'. C compile: 'foo: aText Transcript show: aText. Transcript show: i. Transcript cr.'. C compile: 'i: anInt i := anInt.'. o := C newWithi: 42. o foo: 'This is foo: '. Executing this entire piece of code yields: This is foo: 42 When I would like to have: Caught: This is foo: 42 I was told about wrapper objects and MethodWrapper (see http://stackoverflow.com/questions/15975340/interception-messages-in-squeak) but in my quest to understand reflection, I would like to know if there would be something more "reflective", typically overriding a message :-) Thank you very much in advance! Yann -- Yann-Gaël Guéhéneuc Ph.D. et ing. / Ph.D. and eng. Professeur titulaire / Full professor Chaire de recherche du Canada sur les Patrons (de) logiciels / Canada Research Chair on Software Patterns and Patterns of Software DGIGL, École Polytechnique 1-514-340-4711 #7116 (Tél. / Phone) C.P. 6079, succ. Centre-Ville 1-514-340-5139 (Téléc. / Fax) Montréal, QC, H3C 3A7, Canada www.ptidej.net |
On Mon, Apr 15, 2013 at 01:17:40PM +0900, Yann-Ga?l Gu?h?neuc wrote:
> > Dear all, > > I am trying to understand better reflection in Smalltalk. I am using > the latest version of Squeak (v4.3). I want to intercept every > message sent to instances of one of my classes. I assumed that I > could override the method `ProtoObject>>withArgs:executeMethod` but > St?phane (Ducasse) explained me that for performance reason, this > method is not used (this is my own summary of his answer). Which > method should I override / how could intercept sent messages? > > Here is the code of my attempt: > > Object subclass: #C > instanceVariableNames: 'i' > classVariableNames: '' > poolDictionaries: '' > category: 'CSE3009'. > > C class compile: 'newWithi: anInt > ^(self new) i: anInt ; yourself.'. > > C compile: 'withArgs: someArgs executeMethod: aMethod > Transcript show: ''Caught: ''. > ^ super withArgs: someArgs executeMethod aMethod.'. > > C compile: 'foo: aText > Transcript show: aText. > Transcript show: i. > Transcript cr.'. > > C compile: 'i: anInt > i := anInt.'. > > o := C newWithi: 42. > o foo: 'This is foo: '. > > Executing this entire piece of code yields: > > This is foo: 42 > > When I would like to have: > > Caught: This is foo: 42 > > I was told about wrapper objects and MethodWrapper (see > http://stackoverflow.com/questions/15975340/interception-messages-in-squeak) > but in my quest to understand reflection, I would like to know if there > would be something more "reflective", typically overriding a message :-) > > Thank you very much in advance! > Yann Try this after compiling your code: "Ask the class for the compiled method that you want to execute" theCompiledMethod := C compiledMethodAt: #foo: . "Make an array of size one containing the argument, a string" theArguments := { 'This is foo: ' } . "Execute the compiled method as if it was a message send to the object" o withArgs: theArguments executeMethod: theCompiledMethod. ==> Caught: This is foo: 42 Dave |
Hello Dave, Thank you for your answer! But the solution that you suggested does not show the use of reflection as I would like it to: o withArgs: theArguments executeMethod: theCompiledMethod. I must make an explicit use of "withArgs:executeMethod" while I would like to make this use "transparent" to illustrate the "overriding" of the method invocation, any other suggestion? My purpose is to illustrate the use of reflection and differences between C++, Java, and Smalltalk with that respect. I kind of remember that in some version/flavor of Smalltalk, you could "override" the VM mechanism to invoke method, typically by overriding some "withArgs:executeMethod:" when---and only when---using reflection so that performance would not be horrible but that you could still change the behaviour of invocations (at the risk of breaking the whole image if something silly was done, such as not "forwarding" the invocation to the VM after interception). Do I remember wrong? Yann On 15/04/2013 13:59, David T. Lewis wrote: > On Mon, Apr 15, 2013 at 01:17:40PM +0900, Yann-Ga?l Gu?h?neuc wrote: >> >> Dear all, >> >> I am trying to understand better reflection in Smalltalk. I am using >> the latest version of Squeak (v4.3). I want to intercept every >> message sent to instances of one of my classes. I assumed that I >> could override the method `ProtoObject>>withArgs:executeMethod` but >> St?phane (Ducasse) explained me that for performance reason, this >> method is not used (this is my own summary of his answer). Which >> method should I override / how could intercept sent messages? >> >> Here is the code of my attempt: >> >> Object subclass: #C >> instanceVariableNames: 'i' >> classVariableNames: '' >> poolDictionaries: '' >> category: 'CSE3009'. >> >> C class compile: 'newWithi: anInt >> ^(self new) i: anInt ; yourself.'. >> >> C compile: 'withArgs: someArgs executeMethod: aMethod >> Transcript show: ''Caught: ''. >> ^ super withArgs: someArgs executeMethod aMethod.'. >> >> C compile: 'foo: aText >> Transcript show: aText. >> Transcript show: i. >> Transcript cr.'. >> >> C compile: 'i: anInt >> i := anInt.'. >> >> o := C newWithi: 42. >> o foo: 'This is foo: '. >> >> Executing this entire piece of code yields: >> >> This is foo: 42 >> >> When I would like to have: >> >> Caught: This is foo: 42 >> >> I was told about wrapper objects and MethodWrapper (see >> http://stackoverflow.com/questions/15975340/interception-messages-in-squeak) >> but in my quest to understand reflection, I would like to know if there >> would be something more "reflective", typically overriding a message :-) >> >> Thank you very much in advance! >> Yann > > Try this after compiling your code: > > "Ask the class for the compiled method that you want to execute" > theCompiledMethod := C compiledMethodAt: #foo: . > > "Make an array of size one containing the argument, a string" > theArguments := { 'This is foo: ' } . > > "Execute the compiled method as if it was a message send to the object" > o withArgs: theArguments executeMethod: theCompiledMethod. > > ==> Caught: This is foo: 42 > > Dave > > -- Yann-Gaël Guéhéneuc Ph.D. et ing. / Ph.D. and eng. Professeur titulaire / Full professor Chaire de recherche du Canada sur les Patrons (de) logiciels / Canada Research Chair on Software Patterns and Patterns of Software DGIGL, École Polytechnique 1-514-340-4711 #7116 (Tél. / Phone) C.P. 6079, succ. Centre-Ville 1-514-340-5139 (Téléc. / Fax) Montréal, QC, H3C 3A7, Canada www.ptidej.net |
In reply to this post by Yann-Gaël Guéhéneuc
> I am trying to understand better reflection in Smalltalk. I am using
> the latest version of Squeak (v4.3). Just a side note: the latest version is 4.4 Stef |
In reply to this post by Yann-Gaël Guéhéneuc
PS. Stéphane also mentioned Reflectivity and Bifröst, I will look at
them. On 15/04/2013 17:41, Yann-Gaël Guéhéneuc wrote: > > Hello Dave, > > Thank you for your answer! But the solution that you suggested does > not show the use of reflection as I would like it to: > > o withArgs: theArguments executeMethod: theCompiledMethod. > > I must make an explicit use of "withArgs:executeMethod" while I would > like to make this use "transparent" to illustrate the "overriding" of > the method invocation, any other suggestion? > > My purpose is to illustrate the use of reflection and differences > between C++, Java, and Smalltalk with that respect. I kind of > remember that in some version/flavor of Smalltalk, you could > "override" the VM mechanism to invoke method, typically by overriding > some "withArgs:executeMethod:" when---and only when---using > reflection so that performance would not be horrible but that you > could still change the behaviour of invocations (at the risk of > breaking the whole image if something silly was done, such as not > "forwarding" the invocation to the VM after interception). Do I > remember wrong? > > Yann > > On 15/04/2013 13:59, David T. Lewis wrote: >> On Mon, Apr 15, 2013 at 01:17:40PM +0900, Yann-Ga?l Gu?h?neuc wrote: >>> >>> Dear all, >>> >>> I am trying to understand better reflection in Smalltalk. I am using >>> the latest version of Squeak (v4.3). I want to intercept every >>> message sent to instances of one of my classes. I assumed that I >>> could override the method `ProtoObject>>withArgs:executeMethod` but >>> St?phane (Ducasse) explained me that for performance reason, this >>> method is not used (this is my own summary of his answer). Which >>> method should I override / how could intercept sent messages? >>> >>> Here is the code of my attempt: >>> >>> Object subclass: #C >>> instanceVariableNames: 'i' >>> classVariableNames: '' >>> poolDictionaries: '' >>> category: 'CSE3009'. >>> >>> C class compile: 'newWithi: anInt >>> ^(self new) i: anInt ; yourself.'. >>> >>> C compile: 'withArgs: someArgs executeMethod: aMethod >>> Transcript show: ''Caught: ''. >>> ^ super withArgs: someArgs executeMethod aMethod.'. >>> >>> C compile: 'foo: aText >>> Transcript show: aText. >>> Transcript show: i. >>> Transcript cr.'. >>> >>> C compile: 'i: anInt >>> i := anInt.'. >>> >>> o := C newWithi: 42. >>> o foo: 'This is foo: '. >>> >>> Executing this entire piece of code yields: >>> >>> This is foo: 42 >>> >>> When I would like to have: >>> >>> Caught: This is foo: 42 >>> >>> I was told about wrapper objects and MethodWrapper (see >>> http://stackoverflow.com/questions/15975340/interception-messages-in-squeak) >>> but in my quest to understand reflection, I would like to know if there >>> would be something more "reflective", typically overriding a message :-) >>> >>> Thank you very much in advance! >>> Yann >> >> Try this after compiling your code: >> >> "Ask the class for the compiled method that you want to execute" >> theCompiledMethod := C compiledMethodAt: #foo: . >> >> "Make an array of size one containing the argument, a string" >> theArguments := { 'This is foo: ' } . >> >> "Execute the compiled method as if it was a message send to the object" >> o withArgs: theArguments executeMethod: theCompiledMethod. >> >> ==> Caught: This is foo: 42 >> >> Dave >> >> > -- Yann-Gaël Guéhéneuc Ph.D. et ing. / Ph.D. and eng. Professeur agrégé / Associate professor DIRO, Université de Montréal 1-514-343-6111 47497 (Téléphone / Phone) C.P. 6128, succ. Centre-Ville 1-514-343-5834 (Télécopie / Fax) Montréal, QC, H3C 3J7, Canada www.ptidej.net -- Yann-Gaël Guéhéneuc Ph.D. et ing. / Ph.D. and eng. Professeur titulaire / Full professor Chaire de recherche du Canada sur les Patrons (de) logiciels / Canada Research Chair on Software Patterns and Patterns of Software DGIGL, École Polytechnique 1-514-340-4711 #7116 (Tél. / Phone) C.P. 6079, succ. Centre-Ville 1-514-340-5139 (Téléc. / Fax) Montréal, QC, H3C 3A7, Canada www.ptidej.net |
In reply to this post by Yann-Gaël Guéhéneuc
I take it you're looking for something lower-level than overriding
doesNotUnderstand:. I don't know if this meets your qualifications, but one thing Magma does for its write-barrier is dynamically compile an anonymous subclass of the classes wanting to be overridden. Then use #primitiveChangeClassTo: to change the class of existing instances to the anonymous class. On Sun, Apr 14, 2013 at 11:17 PM, Yann-Gaël Guéhéneuc <[hidden email]> wrote: > > Dear all, > > I am trying to understand better reflection in Smalltalk. I am using the > latest version of Squeak (v4.3). I want to intercept every message sent to > instances of one of my classes. I assumed that I could override the method > `ProtoObject>>withArgs:executeMethod` but Stéphane (Ducasse) explained me > that for performance reason, this method is not used (this is my own summary > of his answer). Which method should I override / how could intercept sent > messages? > > Here is the code of my attempt: > > Object subclass: #C > instanceVariableNames: 'i' > classVariableNames: '' > poolDictionaries: '' > category: 'CSE3009'. > > C class compile: 'newWithi: anInt > ^(self new) i: anInt ; yourself.'. > > C compile: 'withArgs: someArgs executeMethod: aMethod > Transcript show: ''Caught: ''. > ^ super withArgs: someArgs executeMethod aMethod.'. > > C compile: 'foo: aText > Transcript show: aText. > Transcript show: i. > Transcript cr.'. > > C compile: 'i: anInt > i := anInt.'. > > o := C newWithi: 42. > o foo: 'This is foo: '. > > Executing this entire piece of code yields: > > This is foo: 42 > > When I would like to have: > > Caught: This is foo: 42 > > I was told about wrapper objects and MethodWrapper (see > http://stackoverflow.com/questions/15975340/interception-messages-in-squeak) > but in my quest to understand reflection, I would like to know if there > would be something more "reflective", typically overriding a message :-) > > Thank you very much in advance! > Yann > > -- > Yann-Gaël Guéhéneuc > Ph.D. et ing. / Ph.D. and eng. > Professeur titulaire / Full professor > Chaire de recherche du Canada sur les Patrons (de) logiciels / > Canada Research Chair on Software Patterns and Patterns of Software > DGIGL, École Polytechnique 1-514-340-4711 #7116 (Tél. / Phone) > C.P. 6079, succ. Centre-Ville 1-514-340-5139 (Téléc. / Fax) > Montréal, QC, H3C 3A7, Canada www.ptidej.net > |
In reply to this post by Yann-Gaël Guéhéneuc
Hi Yann:
On 15 Apr 2013, at 10:41, Yann-Gaël Guéhéneuc <[hidden email]> wrote: > I kind of remember that in some version/flavor of Smalltalk, you could "override" the VM mechanism to invoke method, typically by overriding some "withArgs:executeMethod:" when---and only when---using reflection so that performance would not be horrible but that you could still change the behaviour of invocations (at the risk of breaking the whole image if something silly was done, such as not "forwarding" the invocation to the VM after interception). Do I remember wrong? Perhaps you remember reading: 'Efficient Method Lookup Customization for Smalltalk'? http://link.springer.com/chapter/10.1007/978-3-642-30561-0_10 There is also PHANtom (http://pleiad.cl/research/software/phantom) and AspectS that might be more high-level. Best regards Stefan -- Stefan Marr Software Languages Lab Vrije Universiteit Brussel Pleinlaan 2 / B-1050 Brussels / Belgium http://soft.vub.ac.be/~smarr Phone: +32 2 629 2974 Fax: +32 2 629 3525 |
Hi all! Thank Chris and Stefan, I will look at Magma, PHANtom and, indeed, the paper 'Efficient Method Lookup Customization for Smalltalk' seems related to what I remember from my school days :-) I will read it, thanks again! Cheers! Yann On 16/04/2013 06:53, Stefan Marr wrote: > Hi Yann: > > On 15 Apr 2013, at 10:41, Yann-Gaël Guéhéneuc <[hidden email]> wrote: > >> I kind of remember that in some version/flavor of Smalltalk, you could "override" the VM mechanism to invoke method, typically by overriding some "withArgs:executeMethod:" when---and only when---using reflection so that performance would not be horrible but that you could still change the behaviour of invocations (at the risk of breaking the whole image if something silly was done, such as not "forwarding" the invocation to the VM after interception). Do I remember wrong? > > Perhaps you remember reading: 'Efficient Method Lookup Customization for Smalltalk'? http://link.springer.com/chapter/10.1007/978-3-642-30561-0_10 > > There is also PHANtom (http://pleiad.cl/research/software/phantom) > and AspectS that might be more high-level. > > Best regards > Stefan > -- Yann-Gaël Guéhéneuc Ph.D. et ing. / Ph.D. and eng. Professeur titulaire / Full professor Chaire de recherche du Canada sur les Patrons (de) logiciels / Canada Research Chair on Software Patterns and Patterns of Software DGIGL, École Polytechnique 1-514-340-4711 #7116 (Tél. / Phone) C.P. 6079, succ. Centre-Ville 1-514-340-5139 (Téléc. / Fax) Montréal, QC, H3C 3A7, Canada www.ptidej.net |
Free forum by Nabble | Edit this page |