From: Robert Klemme Date: 2007-07-22T18:10:38+09:00 Subject: Re: Is there a replacement for sub? On 22.07.2007 04:36, Michael W. Ryder wrote: > dblack@wobblini.net wrote: >> Hi -- >> >> On Sat, 21 Jul 2007, Michael W. Ryder wrote: >> >>> Sebastian Hungerecker wrote: >>>> Michael W. Ryder wrote: >>>>> Martin DeMello wrote: >>>> >>>>>> 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" >>>>> Wrong. >>>> >>>> Nope. >>>> >>>>> Unless you use b = a.dup b will be the same as a as it is pointing >>>>> to the same object. >>>> >>>> Yes. >>>> >>>>> The result of the sub operation will change b as well as a. >>>> >>>> No, sub won't change the actual string - that's what sub! would do. >>>> It will >>>> create a new string which will be assigned to a, at which point a >>>> and b won't >>>> be pointing at the same object anymore. >>>> >>>> >>> My mistake. Too many tests with and without the ! operator. I guess >>> that my test used sub! instead of sub. This just proves my point >>> that the whole thing is too confusing. >> >> Keep in mind that the ! means that the method is the "dangerous" >> version. In this case, the danger consists of both the changing of >> the object in place, and the returning of nil when there's no change. >> Any time you see a ! in a method name you've been warned that there's >> probably something you need to be particular aware of and careful >> about. >> > Unfortunately, my background has always been that a function never > returns nil if nothing is done. C has the ++ operator which can be very > dangerous but it never returns nil. It may be safer to use a = a + 1 or > even better b = a + 1, but I don't have to worry that a++ will return 0 > unless a was -1 before. I realize that the ! operator is a shortcut, but > if it is going to be a shortcut that is all it should be. It seems there is some confusion around: the only "! operator" there is in Ruby is the logical "not" as in "if ! (x > 10) then...". The exclamation mark you are talking about is a part of the method identifier just like the "s". > They current > way it is used with sub and gsub is that sometimes it returns the > results in the specified object and other times it wipes out the > object. There is no wiping out going on. gsub!, sub! and other methods are defined to return "self" (the object you invoke the method on) if there were changes and "nil" if there were no changes. That's the contract and it's documented. Moreover that's pretty consistently adhered to although there are other methods that change the receiver that do not have an exclamation mark in their identifier. > This makes it Very hard to write a program where you are not > always sure of the data, which in my case is a lot of the time. > For example if I was cleaning a data file from a customer where he used > dashes in a Social Security Number and I only wanted to remove up to the > first two dashes in the number, knowing that if more are present that > the number is invalid, I would use a variant of sub. I would not want > to have to program for cases where there were no or one dash in the > number. You don't have to. Just do 2.times { ssn.sub! /-/, '' } or ssn.sub! /-([^-)*)-/, '\\1' > True, I could spend a lot of time trying to catch every > abnormality, but then where is the advantage in using a language like > Ruby, when I could do less work with a "primitive" language that does > what I want without having to check what it is doing. As I said, you do not have to. It seems you haven't accustomed yourself to Ruby or maybe OO programming in general. It took me quite some time to grok OO when I was first exposed to it (using Borland's Turbo Pascal at the time), but once you get the hang of it things fall into place very nicely. > I am not saying that Ruby is a "bad" language, as it has a lot of very > nice features. My problem is that I am not always expecting some of the > idiosyncrasies of the language. When I see something like sub! I expect > that it will return my string with the substitution made or the > unchanged string, not a nil. As you say, it's /your/ problem. :-) I think this will go away pretty soon as you get accustomed to the language. Kind regards robert