From: "Michael W. Ryder" <_mwryder@...> Date: 2007-07-23T11:40:07+09:00 Subject: Re: Is there a replacement for sub? dblack@wobblini.net wrote: > Hi -- > > On Sun, 22 Jul 2007, Bernard Kenik wrote: > >> ruby-talk-admin@ruby-lang.org wrote: >>> >>> >>> >>> ------------------------------------------------------------------------ >>> >>> Subject: >>> Re: Is there a replacement for sub? >>> From: >>> "Robert Dober" >>> Date: >>> Fri, 20 Jul 2007 20:49:07 +0900 >>> To: >>> ruby-talk@ruby-lang.org (ruby-talk ML) >>> >>> To: >>> ruby-talk@ruby-lang.org (ruby-talk ML) >>> >>> >>> On 7/20/07, Martin DeMello wrote: >>>> On 7/20/07, Robert Dober wrote: >>>> > >>>> > I was reading this whole thread and I kind of think to be dreaming, I >>>> > must have missed something obvious!!! >>>> > Anyway maybe this is was OP wants, well I think it is ;) >>>> > >>>> > 529/29 > irb >>>> > irb(main):001:0> a='a b c d e f' >>>> > => "a b c d e f" >>>> > irb(main):002:0> a.gsub!(" ","") >>>> >>>> Nope, he wants a method that only replaces the first n occurrences of >>>> the pattern. gsub will not do this - you need to run sub in a loop. >>>> (This is where perl's "continue matching where you left off" would >>>> have been a nice optimisation) >> >> The primary problem is that sub! returns nil when no substitutions are >> made. >> >> I have similar problem with Array#flatten!, Array#uniq! since it >> causes problem when chaining! >> My solution has been to override these bang! methods to return self >> even when the bang! method did not have to change the receiver. >> >> for sub! I would override the sub! method as follow >> >> class String >> alias old_sub! sub! >> def sub!(pattern, replacement) >> self.old_sub!(pattern, replacement) >> self >> end >> end >> >> As a user of a method, I really do not care if the method did not have >> to do anything so long as the object is in the desired state. >> >> For an array such as arr = [1,2,3,4,5,6], I can safely chain the >> bang! methods without worrying about nil returns from flatten! and uniq! >> >> arr.flatten!.uniq!.sort! # NO ERROR MSG "undefined method `uniq!' >> for nil:NilClass (NoMethodError)" because flatten! would have returned >> nil >> p arr => [1, 2, 3, 4, 5, 6] > > I would very, very strongly advise you, and everyone else, not to do > this. You will break any code (inside the standard library and/or any > other code you load, or any code that uses your code) that depends on > the documented behavior of these methods. You may not like how sub! > and friends work, but it's a very bad idea to make the decision to > change them on behalf of everyone else, over and above the language > documentation. > > What I planned to do was get rid of the alias and change the name of the new sub! method to something like subf! for just that reason. I still prefer this version much better than the original version as there are no surprises. It is very hard to change 30+ years of practice overnight. > David >