String literal at:put: question

David N. Smith (IBM) dnsmith at watson.ibm.com
Mon Jan 1 19:40:59 UTC 2001


At 19:20 -0800 12/31/00, Andrew P. Black wrote:
>>Actually, it's not too hard to create a ReadOnlyString and ReadOnlyArray
>>which have several methods overridden to produce errors.  Overriding at:
>>and basicAt: goes an awefully long way.  Then, the Parser needs to be
>>updated.  I did this once, but it was in an image too divergent from the
>>main Squeak image that it could really be useful.  :|
>
>Is it necessary to change the parser?
>
>I had been thinking instead about changing the behavior of class String so that Strings are immutable (by redefining at:put:, replaceFrom:to:with:startingAt:, byteAt:put: and what else?), and creating a separate class MutableString for those few places where string mutation is really used.  I wonder how common this behavior is.
>
>One tricky thing is that string mutation is sometimes used to create a string that will then be treated as immutable.  See, for example, Symbol asString.  This could (and probably should) be changed to use String withAll: aSymbol.  Mutating a string is OK while it is being constructed (how else could it be constructed?, but taboo once it has been handed off to the world.)
>
>	Andrew

Guys:

For whatever it's worth in this discussion, IBM Smalltalk implements read/only objects. Some objects, like literals, come r/o, but any object can be set r/o as desired. Object supports #isReadOnly and #markReadOnly:; the latter takes a boolean.

When an attempt is made to store into a r/o object the message #attemptedROMStore:intoSlot: is sent to the object, passing the object that was to be stored and its instance variable index; a default implementation in Object simply raises a primitive error.

For objects that have indexed instance variables, the VM checks for the error and fails primitives, such as #basicAt:put:, which in turn check the return code for a r/o store attempt and send #attemptedROMStore:intoSlot:.
	Fails: 'asdf' at: 1 put: $x

Objects with named instance variables, such as Points, seem to be sent #attemptedROMStore:intoSlot:. directly from the VM if they are r/o.
	Fails: ((2 at 3) markReadOnly: true; yourself) x: 3

#attemptedROMStore:intoSlot: can be overridden; if it answers true then the store is retried. Thus objects can be marked as r/o and stored into depending on runtime conditions. It is also possible to set self to r/w, do the store using the slot index, and set self back to r/o.

Note that setting an array to r/o does NOT set its contents to r/o.

The last time I played with this it was very slow; an implementation of active variables (where a store was always allowed but dependents were notified each time a store occurred) took 50 times longer to store (with no dependents) than simple r/w store. I didn't measure the time to get just the indication of an error; it may well be that the VM is fast and the overhead is in the Smalltalk code I wrote to implement active variables.

In the base image there are no users of #attemptedROMStore:intoSlot:, but since there is tons of code that can be loaded from libraries, something may use it.

Dave
-- 
_______________________________
David N. Smith
IBM T J Watson Research Center
Hawthorne, NY
_______________________________
Any opinions or recommendations
herein are those of the author  
and not of his employer.





More information about the Squeak-dev mailing list