Is there a way to override an instance method w/o subclassing?
For instance, class Morph has a method that returns true, but I want the that method to return false when instancing some types of Morphs and others not. (there is no setter/getter for this method.) Is there a way to do that w/o adding a setter/getter to Morph or subclassing the different Morphs? |
Avi's "Singletons" package might be what you're looking for..
On 9/18/07, Brad Fuller <[hidden email]> wrote: > Is there a way to override an instance method w/o subclassing? > For instance, class Morph has a method that returns true, but I want the > that > method to return false when instancing some types of Morphs and others not. > (there is no setter/getter for this method.) Is there a way to do that w/o > adding a setter/getter to Morph or subclassing the different Morphs? > > |
On Tue September 18 2007, Chris Muller wrote:
> Avi's "Singletons" package might be what you're looking for.. Hmm... Is that anything like the Singleton pattern of having only one instance of a class? That's not what I'm looking for. I want many instances. > > On 9/18/07, Brad Fuller <[hidden email]> wrote: > > Is there a way to override an instance method w/o subclassing? > > For instance, class Morph has a method that returns true, but I want the > > that > > method to return false when instancing some types of Morphs and others > > not. (there is no setter/getter for this method.) Is there a way to do > > that w/o adding a setter/getter to Morph or subclassing the different > > Morphs? |
In reply to this post by Brad Fuller-2
On Tue, Sep 18, 2007 at 03:14:15PM -0700, Brad Fuller wrote:
> Is there a way to override an instance method w/o subclassing? > For instance, class Morph has a method that returns true, but I want the that > method to return false when instancing some types of Morphs and others not. > (there is no setter/getter for this method.) Is there a way to do that w/o > adding a setter/getter to Morph or subclassing the different Morphs? Your question is pretty vague I imagine you see something like isMorph ^ true in class morph, but you want some (or all?) morphs to instead use isMorph ^ self isSomethingWeirdHappening not First you can redefine the method in the appropriate class(es). If you want to put this change in a MC package, move it to category *MyPackage-override and this method will be stored in the package, and will override the existing method when loaded. Package-level overrides are not recommended, but they are available -- Matthew Fulmer -- http://mtfulmer.wordpress.com/ Help improve Squeak Documentation: http://wiki.squeak.org/squeak/808 |
On Tue September 18 2007, Matthew Fulmer wrote:
> On Tue, Sep 18, 2007 at 03:14:15PM -0700, Brad Fuller wrote: > > Is there a way to override an instance method w/o subclassing? > > For instance, class Morph has a method that returns true, but I want the > > that method to return false when instancing some types of Morphs and > > others not. (there is no setter/getter for this method.) Is there a way > > to do that w/o adding a setter/getter to Morph or subclassing the > > different Morphs? > > Your question is pretty vague > > I imagine you see something like > > isMorph > ^ true > > in class morph, but you want some (or all?) morphs to instead > use > > isMorph > ^ self isSomethingWeirdHappening not > > First you can redefine the method in the appropriate class(es). If you > want to put this change in a MC package, move it to category > > *MyPackage-override > > and this method will be stored in the package, and will override > the existing method when loaded. > > Package-level overrides are not recommended, but they are available But doesn't that just replace the method? I don't want to change the original class nor do I want to subclass. |
In reply to this post by Brad Fuller-2
Nope. Not about the GoF Singleton pattern at all.
More like Ruby singleton methods. Which is about an instance or instances that have methods that aren't defined in the class for all objects. http://map.squeak.org/accountbyid/04ec7571-cb7e-47ea-b1fc-218f7ec45adc/package/9d63f342-30e3-4db2-8695-3d65ccf28100 "This package adds the #becomeSingleton method to Object, which will transform the receiver into an instance of a new, anonymous subclass of its original class. This lets you add or redefine methods on an object-by-object basis." On 9/18/07, Brad Fuller <[hidden email]> wrote: > On Tue September 18 2007, Chris Muller wrote: > > Avi's "Singletons" package might be what you're looking for.. > > Hmm... Is that anything like the Singleton pattern of having only one instance > of a class? That's not what I'm looking for. I want many instances. > > > > > On 9/18/07, Brad Fuller <[hidden email]> wrote: > > > Is there a way to override an instance method w/o subclassing? > > > For instance, class Morph has a method that returns true, but I want the > > > that > > > method to return false when instancing some types of Morphs and others > > > not. (there is no setter/getter for this method.) Is there a way to do > > > that w/o adding a setter/getter to Morph or subclassing the different > > > Morphs? > > > > |
cool. I'll check it out.
On Tue September 18 2007, David Mitchell wrote: > Nope. Not about the GoF Singleton pattern at all. > > More like Ruby singleton methods. Which is about an instance or > instances that have methods that aren't defined in the class for all > objects. > > http://map.squeak.org/accountbyid/04ec7571-cb7e-47ea-b1fc-218f7ec45adc/pack >age/9d63f342-30e3-4db2-8695-3d65ccf28100 > > "This package adds the #becomeSingleton method to Object, which will > transform the receiver into an instance of a new, anonymous subclass > of its original class. This lets you add or redefine methods on an > object-by-object basis." > > On 9/18/07, Brad Fuller <[hidden email]> wrote: > > On Tue September 18 2007, Chris Muller wrote: > > > Avi's "Singletons" package might be what you're looking for.. > > > > Hmm... Is that anything like the Singleton pattern of having only one > > instance of a class? That's not what I'm looking for. I want many > > instances. > > > > > On 9/18/07, Brad Fuller <[hidden email]> wrote: > > > > Is there a way to override an instance method w/o subclassing? > > > > For instance, class Morph has a method that returns true, but I want > > > > the that > > > > method to return false when instancing some types of Morphs and > > > > others not. (there is no setter/getter for this method.) Is there a > > > > way to do that w/o adding a setter/getter to Morph or subclassing the > > > > different Morphs? |
In reply to this post by Brad Fuller-2
On 9/18/07, Brad Fuller <[hidden email]> wrote:
> On Tue September 18 2007, Chris Muller wrote: > > Avi's "Singletons" package might be what you're looking for.. > > Hmm... Is that anything like the Singleton pattern of having only one instance > of a class? That's not what I'm looking for. I want many instances. No, it isn't. The name is misleading. It's... Well, just read it! http://map1.squeakfoundation.org/package/9d63f342-30e3-4db2-8695-3d65ccf28100 |
In reply to this post by Brad Fuller-2
On Tue, Sep 18, 2007 at 05:57:02PM -0700, Brad Fuller wrote:
> But doesn't that just replace the method? I don't want to change the original > class nor do I want to subclass. Well then, what DO you want to do? -- Matthew Fulmer -- http://mtfulmer.wordpress.com/ Help improve Squeak Documentation: http://wiki.squeak.org/squeak/808 |
In reply to this post by Brad Fuller-2
On 9/19/07, Brad Fuller <[hidden email]> wrote: Is there a way to override an instance method w/o subclassing? Er... my immediate suspicion is that you'd want to take a step back and ask yourself /why/ you're doing this. There is some black magic you can do to achieve this hackery, but beware, this is very powerful magic and many images have been killed in its making. Before you run your test, save your image. Do not save your image after running your test; instead, trash the image and start it up again from your save. Install this: http://www.squeaksource.com/DPON/MessageCapture-mvdg.9.mcz, try to understand it and let me know if you can't understand my comments. Set up message capture on the Morph you want. Implement a message handler to do the logic you need for one set of clients and give them the MessageCapture object. Give the original Morph to the other objects. Good luck! And remember - don't save your image after you run this until you're sure it works. The debugger and inspector will crash the image if you try to use them. Another way would be to inspect thisContext to see who the sender is and do conditional logic that way. Regards, Gulik. |
In reply to this post by Brad Fuller-2
On Tue September 18 2007, Brad Fuller wrote:
> Is there a way to override an instance method w/o subclassing? > For instance, class Morph has a method that returns true, but I want the > that method to return false when instancing some types of Morphs and others > not. (there is no setter/getter for this method.) Is there a way to do that > w/o adding a setter/getter to Morph or subclassing the different Morphs? Thanks everyone, I think I have to go on for now. |
In reply to this post by Brad Fuller-2
On 19/09/2007, Brad Fuller <[hidden email]> wrote:
> On Tue September 18 2007, Matthew Fulmer wrote: > > On Tue, Sep 18, 2007 at 03:14:15PM -0700, Brad Fuller wrote: > > > Is there a way to override an instance method w/o subclassing? > > > For instance, class Morph has a method that returns true, but I want the > > > that method to return false when instancing some types of Morphs and > > > others not. (there is no setter/getter for this method.) Is there a way > > > to do that w/o adding a setter/getter to Morph or subclassing the > > > different Morphs? > > > > Your question is pretty vague > > > > I imagine you see something like > > > > isMorph > > ^ true > > > > in class morph, but you want some (or all?) morphs to instead > > use > > > > isMorph > > ^ self isSomethingWeirdHappening not > > > > First you can redefine the method in the appropriate class(es). If you > > want to put this change in a MC package, move it to category > > > > *MyPackage-override > > > > and this method will be stored in the package, and will override > > the existing method when loaded. > > > > Package-level overrides are not recommended, but they are available > > But doesn't that just replace the method? I don't want to change the original > class nor do I want to subclass. > > Suppose you have a class , which is a subclass of interesting class, where you override method(s). Then, at package initialization (or even before invoking some code, where you need a replacement) you can do: backupClass := Morph. Smalltalk at: #Morph put: MyMorphWithOverrides. .... run code ... "restore original class" Smalltalk at: #Morph put: backupClass. -- Best regards, Igor Stasenko AKA sig. |
or another way:
oldMethod := Morph methodDictionary at: #isMorph. Morph methodDictionary at: #isMorph put: newCompiledMethod. -- Best regards, Igor Stasenko AKA sig. |
> oldMethod := Morph methodDictionary at: #isMorph.
> Morph methodDictionary at: #isMorph put: newCompiledMethod. Or use Classboxes [1] to solve this problem automatically. Lukas [1] http://www.iam.unibe.ch/~scg/Research/Classboxes/ -- Lukas Renggli http://www.lukas-renggli.ch |
In reply to this post by David Mitchell-10
In Squeak this is usually called "uniclasses" (for Unique Class) as a
way to add methods to instances. It's in the base system - send #assureUniClass to the instance. What's the difference of this to #becomeSingleton? - Bert - On Sep 19, 2007, at 3:50 , David Mitchell wrote: > Nope. Not about the GoF Singleton pattern at all. > > More like Ruby singleton methods. Which is about an instance or > instances that have methods that aren't defined in the class for all > objects. > > http://map.squeak.org/accountbyid/04ec7571-cb7e-47ea- > b1fc-218f7ec45adc/package/9d63f342-30e3-4db2-8695-3d65ccf28100 > > "This package adds the #becomeSingleton method to Object, which will > transform the receiver into an instance of a new, anonymous subclass > of its original class. This lets you add or redefine methods on an > object-by-object basis." > > On 9/18/07, Brad Fuller <[hidden email]> wrote: >> On Tue September 18 2007, Chris Muller wrote: >>> Avi's "Singletons" package might be what you're looking for.. >> >> Hmm... Is that anything like the Singleton pattern of having only >> one instance >> of a class? That's not what I'm looking for. I want many instances. >> >>> >>> On 9/18/07, Brad Fuller <[hidden email]> wrote: >>>> Is there a way to override an instance method w/o subclassing? >>>> For instance, class Morph has a method that returns true, but I >>>> want the >>>> that >>>> method to return false when instancing some types of Morphs and >>>> others >>>> not. (there is no setter/getter for this method.) Is there a way >>>> to do >>>> that w/o adding a setter/getter to Morph or subclassing the >>>> different >>>> Morphs? >> >> >> >> > |
In reply to this post by Brad Fuller-2
Hi Brad,
I realize you have moved on but there are two more I thought I'd mention. You could wrap your class if you do not want to change it. Simply create a wrapper class, then change does not understand to pass messages that you didn't override to the class. Then you can override your class all you want by simply implementing the messages you want to override on the wrapper class. So for example: Object subclass: #Radio Radio class >> bands "return the receiving bands that this class handles" ^#('FM' 'AM') Object subclass: #RadioWrapper instanceVariableNames: 'subject' RadioWrapper class >> doesNotUnderstand: aMessage "Handle messages that are not implemented on this wrapper by passing them to #subject" ^self subject class perform: aMessage. RadioWrapper >> doesNotUnderstand: aMessage "Handle messages that are not implemented on this wrapper by passing them to #subject" ^self subject perform: aMessage. Now you can override RadioWrapper class >> bands "override the base method to add 'HD'" ^self subject bands copyWith: 'HD'. To use your new class you need to wrap your class RadioWrapper class >> wrap: aRadio "wrap the radio class for overrides" ^self new subject: aRadio; yourself now in your code you need to change instances of Radio to use your new wrapped class. aRadio := Radio new. Becomes aRadio := RadioWrapper wrap: Radio new. So in your example you could just wrap morphs with a wrapper that changes what you need changed. What's nice about this pattern is that you can wrap multiple levels and they will continue to work, passing down methods that it doesn't understand and handling those that it does. In other words a wrapper can also be wrapped with a different wrapper and it will still work. The down side to this is that every message send that is not implemented on your wrapped class has additional overhead so this is not recommended if performance is a concern. The overhead is minimal and usually not a problem. The second method if you have an instvar that needs to be changed is to break encapsulation completely by using instVarAt: to set the value directly. This is really not a good idea and can cause a lot of problems that are difficult to diagnose. (Don't tell anyone I recommend this :) ) Hope that helps, Ron Teitelbaum > -----Original Message----- > From: Brad Fuller > > On Tue September 18 2007, Brad Fuller wrote: > > Is there a way to override an instance method w/o subclassing? > > For instance, class Morph has a method that returns true, but I want the > > that method to return false when instancing some types of Morphs and > others > > not. (there is no setter/getter for this method.) Is there a way to do > that > > w/o adding a setter/getter to Morph or subclassing the different Morphs? > > Thanks everyone, I think I have to go on for now. > > |
Thanks, Ron. I've read and heard about this, but to me it looks dangerous and
would seem to incur overhead so I always avoided entertaining the idea. But, it's interesting. ALWAYS nice to have an example and I thank you for the extended example. Very helpful! On Wed September 19 2007, Ron Teitelbaum wrote: > Hi Brad, > > I realize you have moved on but there are two more I thought I'd mention. > > You could wrap your class if you do not want to change it. Simply create a > wrapper class, then change does not understand to pass messages that you > didn't override to the class. Then you can override your class all you > want by simply implementing the messages you want to override on the > wrapper class. > > So for example: > > Object subclass: #Radio > > Radio class >> bands > "return the receiving bands that this class handles" > ^#('FM' 'AM') > > Object subclass: #RadioWrapper > instanceVariableNames: 'subject' > > RadioWrapper class >> doesNotUnderstand: aMessage > "Handle messages that are not implemented on this wrapper by passing > them to #subject" > ^self subject class perform: aMessage. > > RadioWrapper >> doesNotUnderstand: aMessage > "Handle messages that are not implemented on this wrapper by passing > them to #subject" > ^self subject perform: aMessage. > > Now you can override > > RadioWrapper class >> bands > "override the base method to add 'HD'" > ^self subject bands copyWith: 'HD'. > > To use your new class you need to wrap your class > > RadioWrapper class >> wrap: aRadio > "wrap the radio class for overrides" > ^self new > subject: aRadio; > yourself > > now in your code you need to change instances of Radio to use your new > wrapped class. > > aRadio := Radio new. > > Becomes > > aRadio := RadioWrapper wrap: Radio new. > > So in your example you could just wrap morphs with a wrapper that changes > what you need changed. What's nice about this pattern is that you can wrap > multiple levels and they will continue to work, passing down methods that > it doesn't understand and handling those that it does. In other words a > wrapper can also be wrapped with a different wrapper and it will still > work. > > The down side to this is that every message send that is not implemented on > your wrapped class has additional overhead so this is not recommended if > performance is a concern. The overhead is minimal and usually not a > problem. > > The second method if you have an instvar that needs to be changed is to > break encapsulation completely by using instVarAt: to set the value > directly. This is really not a good idea and can cause a lot of problems > that are difficult to diagnose. (Don't tell anyone I recommend this :) ) > > Hope that helps, > > Ron Teitelbaum > > > -----Original Message----- > > From: Brad Fuller > > > > On Tue September 18 2007, Brad Fuller wrote: > > > Is there a way to override an instance method w/o subclassing? > > > For instance, class Morph has a method that returns true, but I want > > > the that method to return false when instancing some types of Morphs > > > and > > > > others > > > > > not. (there is no setter/getter for this method.) Is there a way to do > > > > that > > > > > w/o adding a setter/getter to Morph or subclassing the different > > > Morphs? > > > > Thanks everyone, I think I have to go on for now. |
In reply to this post by Bert Freudenberg
Agents were already there in Squeak!
Thanks, i've learned something Bert Freudenberg a écrit : > In Squeak this is usually called "uniclasses" (for Unique Class) as a > way to add methods to instances. It's in the base system - send > #assureUniClass to the instance. > > What's the difference of this to #becomeSingleton? > > - Bert - > > On Sep 19, 2007, at 3:50 , David Mitchell wrote: > >> Nope. Not about the GoF Singleton pattern at all. >> >> More like Ruby singleton methods. Which is about an instance or >> instances that have methods that aren't defined in the class for all >> objects. >> >> http://map.squeak.org/accountbyid/04ec7571-cb7e-47ea-b1fc-218f7ec45adc/package/9d63f342-30e3-4db2-8695-3d65ccf28100 >> >> >> "This package adds the #becomeSingleton method to Object, which will >> transform the receiver into an instance of a new, anonymous subclass >> of its original class. This lets you add or redefine methods on an >> object-by-object basis." >> |
In reply to this post by Bert Freudenberg
Apparently terminology.
Also, it appears that Avi's Singleton's package isn't available anymore (the link on Squeak Map points to the beta4.com site that has been taken over by one of those search engines that sit on domain names. I went to go look in more detail. I knew eToys did prototype or instance based programming, but never new how. I also didn't know there was a concept called UniClasses. I'm fairly well read on Squeak (been on the list since 96-97), reviewed Guzdial's blue book, read his white book, Steph's robot book, and I'm working through SBE. I've recently been hearing a lot about singleton methods from Ruby, so that's why I chimed in. Thanks for the redirect. Will start learning more about UniClasses! On 9/19/07, Bert Freudenberg <[hidden email]> wrote: > In Squeak this is usually called "uniclasses" (for Unique Class) as a > way to add methods to instances. It's in the base system - send > #assureUniClass to the instance. > > What's the difference of this to #becomeSingleton? > > - Bert - > > On Sep 19, 2007, at 3:50 , David Mitchell wrote: > > > Nope. Not about the GoF Singleton pattern at all. > > > > More like Ruby singleton methods. Which is about an instance or > > instances that have methods that aren't defined in the class for all > > objects. > > > > http://map.squeak.org/accountbyid/04ec7571-cb7e-47ea- > > b1fc-218f7ec45adc/package/9d63f342-30e3-4db2-8695-3d65ccf28100 > > > > "This package adds the #becomeSingleton method to Object, which will > > transform the receiver into an instance of a new, anonymous subclass > > of its original class. This lets you add or redefine methods on an > > object-by-object basis." > > > > On 9/18/07, Brad Fuller <[hidden email]> wrote: > >> On Tue September 18 2007, Chris Muller wrote: > >>> Avi's "Singletons" package might be what you're looking for.. > >> > >> Hmm... Is that anything like the Singleton pattern of having only > >> one instance > >> of a class? That's not what I'm looking for. I want many instances. > >> > >>> > >>> On 9/18/07, Brad Fuller <[hidden email]> wrote: > >>>> Is there a way to override an instance method w/o subclassing? > >>>> For instance, class Morph has a method that returns true, but I > >>>> want the > >>>> that > >>>> method to return false when instancing some types of Morphs and > >>>> others > >>>> not. (there is no setter/getter for this method.) Is there a way > >>>> to do > >>>> that w/o adding a setter/getter to Morph or subclassing the > >>>> different > >>>> Morphs? > >> > >> > >> > >> > > > > > > > > |
UniClasses and Players are named+number subclasses that get put into the
UserObjects category. Avis' Singletons package works differently. Travis David Mitchell wrote: > Apparently terminology. > > Also, it appears that Avi's Singleton's package isn't available > anymore (the link on Squeak Map points to the beta4.com site that has > been taken over by one of those search engines that sit on domain > names. > > I went to go look in more detail. > > I knew eToys did prototype or instance based programming, but never > new how. I also didn't know there was a concept called UniClasses. I'm > fairly well read on Squeak (been on the list since 96-97), reviewed > Guzdial's blue book, read his white book, Steph's robot book, and I'm > working through SBE. > > I've recently been hearing a lot about singleton methods from Ruby, so > that's why I chimed in. > > Thanks for the redirect. Will start learning more about UniClasses! > On 9/19/07, Bert Freudenberg <[hidden email]> wrote: > >> In Squeak this is usually called "uniclasses" (for Unique Class) as a >> way to add methods to instances. It's in the base system - send >> #assureUniClass to the instance. >> >> What's the difference of this to #becomeSingleton? >> >> - Bert - >> >> On Sep 19, 2007, at 3:50 , David Mitchell wrote: >> >> >>> Nope. Not about the GoF Singleton pattern at all. >>> >>> More like Ruby singleton methods. Which is about an instance or >>> instances that have methods that aren't defined in the class for all >>> objects. >>> >>> http://map.squeak.org/accountbyid/04ec7571-cb7e-47ea- >>> b1fc-218f7ec45adc/package/9d63f342-30e3-4db2-8695-3d65ccf28100 >>> >>> "This package adds the #becomeSingleton method to Object, which will >>> transform the receiver into an instance of a new, anonymous subclass >>> of its original class. This lets you add or redefine methods on an >>> object-by-object basis." >>> >>> On 9/18/07, Brad Fuller <[hidden email]> wrote: >>> >>>> On Tue September 18 2007, Chris Muller wrote: >>>> >>>>> Avi's "Singletons" package might be what you're looking for.. >>>>> >>>> Hmm... Is that anything like the Singleton pattern of having only >>>> one instance >>>> of a class? That's not what I'm looking for. I want many instances. >>>> >>>> >>>>> On 9/18/07, Brad Fuller <[hidden email]> wrote: >>>>> >>>>>> Is there a way to override an instance method w/o subclassing? >>>>>> For instance, class Morph has a method that returns true, but I >>>>>> want the >>>>>> that >>>>>> method to return false when instancing some types of Morphs and >>>>>> others >>>>>> not. (there is no setter/getter for this method.) Is there a way >>>>>> to do >>>>>> that w/o adding a setter/getter to Morph or subclassing the >>>>>> different >>>>>> Morphs? >>>>>> >>>> >>>> >>>> >> >> >> >> >> > > Singletons-avi.1.mcz (2K) Download Attachment |
Free forum by Nabble | Edit this page |