Hello all -
While experimenting with my new copy of DVE 4.01.3, I came across the following head scratcher: Define a subclass of Array, say Test, and override the #at: method: Test>>at: anIndex ^ super at: index + 1 Now open a workspace and create an instance of Test: t := Test with: 1 with: 2 with: 3 Then access an element: t at: 1 If I execute the first statement with control-E and the second with control-D, the returned value is 2, as I was expecting. The funny thing is, if I execute the first statement with the 'Evaluate It' icon in the toolbar, and the second with the 'Display It' icon, the returned value is 1. Is this the expected behavior? Am I doing something wrong? If not, can anyone duplicate this? TIA, - Sandy Stone |
Happens to me too. I don't think you are supposed to override
primitives because they are compiled differently for efficiency reasons. Try changing it to #atx and you will have no problem. costas On Sun, 19 Aug 2001 01:20:00 GMT, "Sandy Stone" <[hidden email]> wrote: >Hello all - > >While experimenting with my new copy of DVE 4.01.3, I came across the >following head scratcher: > >Define a subclass of Array, say Test, and override the #at: method: > > Test>>at: anIndex > > ^ super at: index + 1 > >Now open a workspace and create an instance of Test: > > t := Test with: 1 with: 2 with: 3 > >Then access an element: > > t at: 1 > >If I execute the first statement with control-E and the second with >control-D, the returned value is 2, as I was expecting. The funny thing is, >if I execute the first statement with the 'Evaluate It' icon in the toolbar, >and the second with the 'Display It' icon, the returned value is 1. Is this >the expected behavior? Am I doing something wrong? If not, can anyone >duplicate this? TIA, > >- Sandy Stone > > |
In reply to this post by Sandy Stone
Sandy Stone wrote:
> If I execute the first statement with control-E and the second with > control-D, the returned value is 2, as I was expecting. The funny thing is, > if I execute the first statement with the 'Evaluate It' icon in the toolbar, > and the second with the 'Display It' icon, the returned value is 1. It's stranger than that. On my machine, if I set up the "t" object as you did, then inspect it, it claims its "self" is #(2 2 3). If I move the selection in the Inspector to one of the sub-elements and back then it now claims that "self" is #(1 2 3). Also, in my first test on my machine both the icon and CTRL+D of t at: 1 produced 1. Weirdly, if I then did an F11 to debug into it, but immediately exited the debugger, then the *next* time I displayed it (using either method), then it evaluated to 2. Most odd. So I opened another workspace, and tried the same thing. In this case it evaluated to 2, every time (again, using either method). As you may guess, I did *not* save that image... I've seen some odd things before (like an image that reliably crashed on W2K, although I can't reproduce it anymore) when subclassing Array. My current rule of thumb is just not to do it. Perhaps someone at OA can comment on what the real limits are. -- chris |
In reply to this post by Sandy Stone
Sandy
You wrote in message news:4vEf7.69$[hidden email]... > > While experimenting with my new copy of DVE 4.01.3, I came across the > following head scratcher: > > Define a subclass of Array, say Test, and override the #at: method: > ... > If I execute the first statement with control-E and the second with > control-D, the returned value is 2, as I was expecting. The funny thing is, > if I execute the first statement with the 'Evaluate It' icon in the toolbar, > and the second with the 'Display It' icon, the returned value is 1. Is this > the expected behavior? Am I doing something wrong? If not, can anyone > duplicate this? TIA, You are seeing the effects of a caching optimisation behind the Object>>at: and Object>>at:put: primitives. The VM optimises the processing of #at: and #at:put: messages to an object if at any time the corresponding primitive is invoked against that object. Subsequently the VM will assume it is OK to completely bypass the message send and perform the "array" access directly itself using previously cached information. This has a pretty dramatic effect on the performance of #at: and #at:put:, especially when used in loops against the same object, however it will break overrides of #at: that supersend #at: to the primitive implementation with a different argument. In general, though, you will have no problems overriding #at: (the base class library itself does it rather a lot), but if you really want to do something like this then you should replace the supersend of #at: that ends in the primitive with a send of #basicAt:, i.e. Test>>at: anInteger ^self basicAt: anInteger + 1 The reason, BTW, that you see different behaviour depending on the way you evaluate the expressions comes down to the difference in behaviour between the first send of #at:, when no information is in the cache, to subsequent sends, when it is. Regards Blair |
In reply to this post by Chris Uppal-3
Chris
You wrote in message news:[hidden email]... > ... > I've seen some odd things before (like an image that reliably crashed on > W2K, although I can't reproduce it anymore) when subclassing Array. It is possible that was due to defect #179 "Object>>at:[put:] primitive GPFs on attempted access to non-indexable object" (actually errors in the range checking performed by the primitives) which was fixed in PL3 iff you downloaded a new installation rather than using Live Update (the fix was to the VM). >...My > current rule of thumb is just not to do it. Perhaps someone at OA can > comment on what the real limits are. There may be some merit in that RoT from a design point of view, but you should be able to subclass Array freely (at least if one avoids the issue discussed in this thread*). Modifying it is another matter, and in particular instance variables cannot be added. Regards Blair *I've recorded this issue as a defect, as it should be possible to detect the case and shut off the optimisation when the primitives are invoked by a supersend. |
In reply to this post by Blair McGlashan
Blair,
Thanks for the info. Now that you point it out, using #basicAt: looks like a better way to proceed anyway. I was a little confused, because apparently this optimization wasn't present in 2.01 and the construction I used worked. Again, thanks for a great product and great support. It's not often that a hobbyist who buys the most inexpensive item in the product line hears directly from the developer. - Sandy Stone |
Free forum by Nabble | Edit this page |