On Jul 22, 10:39 pm, "Michael W. Ryder" <_mwry...@worldnet.att.net> > wrote:
> dbl...@wobblini.net wrote:
> > Hi --
> > On Sun, 22 Jul 2007, Bernard Kenik wrote:
> >> ruby-talk-ad...@ruby-lang.org wrote:
> >>> ------------------------------------------------------------------------
> >>> Subject:
> >>> Re: Is there a replacement for sub?
> >>> From:
> >>> "Robert Dober" <robert.do...@gmail.com>
> >>> Date:
> >>> Fri, 20 Jul 2007 20:49:07 +0900
> >>> To:
> >>> ruby-t...@ruby-lang.org (ruby-talk ML)
> >>> To:
> >>> ruby-t...@ruby-lang.org (ruby-talk ML)
> >>> On 7/20/07, Martin DeMello <martindeme...@gmail.com> wrote:
> >>>> On 7/20/07, Robert Dober <robert.do...@gmail.com> 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- Hide quoted text -
> - Show quoted text -- Hide quoted text -
> - Show quoted text -
Actually you do not have to define subf! as an intermediate step
you can directly define subn and subn! directly
class String
def subn!(pattern, replacement, n = 1)
n.times { self.sub!(pattern, replacement) }
self # or return 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) }
@str # or return @str
end
end
Note that sub and sub! are the original definitions
You use subn(pattern, replacement) and subn!(pattern, replacement) as
substitutes for sub(pattern, replacement) and sub!(pattern,
replacement) which eliminate the unpleasant surprises.
In addition, both can be safely chained !!!!
Hope this helps- Hide quoted text -
- Show quoted text -