From: Martin DeMello Date: 2007-07-20T18:05:34+09:00 Subject: Re: Is there a replacement for sub? On 7/20/07, Michael W. Ryder <_mwryder@worldnet.att.net> wrote: > > Except where you use b = a.sub!(' ', ''). Then if you loop through this > statement 10 times b is nil, not the abcdef I expected. This is what is > so confusing. At the same time I can not use b = a.sub(' ', '') as it > always returns ab c d e f regardless of how many times I execute it, > which is what I would expect. So, how would I do this? > 10.times { b = a.sub!(' ', '')} doesn't work, it errors out. Remember that a variable is not an object, it is just a label pointing to an object. sub: returns a *copy* of the string, with the substitution made (i.e. a new object) sub!: modifies the string in place (i.e. modifies the object itself) Therefore a = "a b c d e f" a.sub(" ", "") # => returns "ab c d e f", but leaves a unchanged. also, the return value will be garbage collected, since nothing is pointing to it b = a.sub(" ", "") # => b is now "ab c d e f", leaves a unchanged a = a.sub(" ", "") # => a is now "ab c d e f", the old string is garbage collected a = "a b c d e f" b = a a = a.sub(" ", "") # => a is now "ab c d e f", b is still "a b c d e f" a = "a b c d e f" a.sub!("", '') #=> a is now "ab c d e f" a = "a b c d e f" b = a.sub!("", '') #=> a is now "ab c d e f", a and b point to the same object a = "abcdef" b = a.sub!("", '') #=> a is still "abcdef", b is nil Note the last bit carefully - sub! modifies the object, and *returns* either another pointer to the same object if it was modified, or nil if it wasn't. Therefore the return value of sub! should ideally only be used to check if the string was modified or not, and then discarded. As for running in a loop, you want either 10.times { a.sub!(" ", '')} #=> modifies a string 10 times or 10.times {a = a.sub(" ", '')} # creates a series of 10 strings, the intermediate ones being GCd try this: a = "a b c d e f" intermediate = [a] 10.times {|i| intermediate[i+1] = intermediate[i].sub(" ", '')} p intermediate # => ["a b c d e f", "ab c d e f", "abc d e f", "abcd e f", "abcde f", "abcdef", "abcdef", "abcdef", "abcdef", "abcdef", "abcdef"] martin