From: "Michael W. Ryder" <_mwryder@...> Date: 2007-07-24T10:15:00+09:00 Subject: Re: Is there a replacement for sub? bbiker wrote: > You might consider adding the following, so you have a matching > replacement set for sub, sub!, gsub, and gsub! > > You can think of gsubn and gsubn! as no nil returns :>) > > class String > def subn!(pattern, replacement, n = 1) > n.times { self.sub!(pattern, replacement) } > self > end > > def subn(pattern, replacement, n = 1) > return self if n < 1 > @str = self.sub(pattern, replacement) > (n-1).times { @str = @str.sub(pattern, replacement) } Is there any reason you used the above three lines instead of: @str = self n.times { @str = @str.sub(pattern, replacement) } As I mentioned in an earlier post times seems to work fine with zero or negative values not changing the string. The replacement code seems "cleaner" but I may be missing some gotcha that your code prevents. Again, thanks for improving my knowledge of Ruby. > @str > end > > def gsubn!(pattern, replacement) > self.gsub!(pattern, replacement) > self # does not return nil if no > changes were made > end > > alias gsubn gsub # you can use either gsubn or gsub > end > > > My primary objection to have a nil return is that it prevents me from > safely chaining bang! methods. > > The nil return is counter-intuitive and violates the Principle of > Least Surprise > > As I said before given an array such as arr = [1, 2, 3, 4, 5, 6], I > can do > > new_arr = arr.flatten.uniq.sort => [1, 2, 3, 4, 5, 6] > > Intuitively I would think that I should be able to do > arr.flatten!.uniq!.sort!; however because of the nil return by > #flatten!, a NoMethodError is raised by #uniq! since the nil object > does not have a uniq! method. > > Note that not all bang! methods return nil when nothing was changed in > the receiver. Array#sort! return self if self was already sorted. > > Hopefully Matz might be reading this thread and might consider > changing the behavior of bang! methods returns. >