From: Brian Candler Date: 2009-01-23T19:35:23+09:00 Subject: Re: String doesnt auto dup on modification RK Sentinel wrote: > Thanks for all the helpful replies. Its my first venture: a widget > library. > > Here's an example: Sometimes a string is passed to a class, say, using > its set_buffer method (which is an _optional_ method). > > set_buffer just assigns it to @buffer. But deep within the class this > variable is being edited using insert() or slice!() (and this IS > necessary) since the widget is an editing widget. Thanks, so I guess the API is something like this: edit_field.buffer = "foo" ... some time later, after user has clicked OK ... f.write(edit_field.buffer) Now, if there is a compelling reason for this object to perform "in-place" editing on the buffer then by all means do, and document this, but it will lead to the aliasing problems you describe. It may be simpler and safer just to use non-destructive methods inside your class. # destructive @buffer.slice!(x,y) # non-destructive alternative @buffer = @buffer.slice(x,y) # destructive @buffer.insert(pos, text) # non-destructive alternative @buffer = buffer[0,pos] + text + buffer[pos..-1] In effect, this is doing a 'dup' each time. It has to; since Ruby doesn't do reference-counting it has no idea whether any other object in the system is holding a reference to the original object or not. The only problem with this is if @buffer is a multi-megabyte object and you don't want to keep copying it. In this case, doing a single dup up-front would allow you to use the destructive methods safely. class Editor def buffer @buffer end def buffer=(x) @buffer = x.dup end end The overhead of a single copy is small, and in any case this is probably what is needed here (e.g. if the user makes some edits but clicks 'cancel' instead of 'save' then you may want to keep the old string untouched) You could try deferring the dup until the first time you call a destructive method on the string, but the complexity overhead is unlikely to be worth it. -- Posted via http://www.ruby-forum.com/.