When I have a method that is applied to instances of a class X that do
not depend on the values of the instances themselves I place those methods on the class side. For the problem at hand the method takes as input a collection of the instances of the class and rearranges them in some way: Such a method might be called: rearrange: aCollection (Actually I lied; the rearrange method depends upon probability values stored in instances of X) To get an instance of the object to do the rearranging (i.e. X) on the instance side of X I have a method: rearranger ^self class This works fine so far but in this particular case X has subclasses and the collection passed to the method "rearrange:" is not impacted by the fact that instances of the subclasses of X may be in the Collection; i.e. everything still works. However, if I send the "rearranger" message to an instance of a subclass Y of X then -- well ok; everything still works. Everything still works because the "rearranger" message now returns a subclass of X which in turn inherits the "rearrange:" method from class X. My only complaint then is that every time the "rearrange:" message is sent inheritance must now be used to find the "rearrange:" method. This seems inefficient to me (I know Squeak is 50 slower than C so who cares) so to fix this I can change method "rearranger" to: rearranger ^X "the class X that is" Problem fixed. However, I have been taught that now the code is written in a brittle i.e. bad way. That is, if I now rename class X to Z then the "rearranger" method becomes broken. Finally, a question: How do I write the method "rearranger" so that it returns the class in which the method is defined rather than the class of the object that received the "rearranger" message? I am looking for something clean here; I can think of some convoluted ways of doing this. I admit that even if this can be done cleanly the code remains more brittle than the original solution. This is because if a subclass of X wants to override method "rearrange:" it must now also override method "rearranger" which was not necessary with the original solution. I am also aware that optimizations are done by the VM to avoid method lookups but I am not sure of the details. Do the details mean that after the first send of "rearrange:" to class Y no further lookups are needed on subsequent sends? to Y. What if "rearrange" is sent to Y from multiple locations in some method or from multiple methods in some class all sending to the same instance variable holding Y? Regards, Ralph Boland |
On 23.01.2010, at 04:08, Ralph Boland wrote:
> > > My only complaint then is that every time the "rearrange:" > message is sent inheritance must now be used to find the > "rearrange:" method. > This seems inefficient to me (I know Squeak is 50 slower than > C so who cares) Please post benchmark code demonstrating the problem. Or at least a profile. I am pretty sure you are misguided in assuming that the depth of method lookup would make any measurable difference in real-world code. Your inner loop would have to be way optimized for that, pretty much running bytecode only. "about 97% of the time, premature optimization is the root of all evil" -- Don Knuth - Bert - |
Free forum by Nabble | Edit this page |