Author |
Message |
Michael Witran #1 / 13
|
 Array#sort! returns nil when array empty
Hello, Array#sort! returns nil if the array is empty, whereas ri says it should return itself: arr.sort! -> arr irb(main):007:0> [3,1,2].sort! [1, 2, 3] irb(main):008:0> [].sort! nil irb(main):009:0> [3,1,2].sort [1, 2, 3] irb(main):010:0> [].sort [] Mike. midulo.
|
Mon, 29 Dec 2003 23:29:38 GMT |
|
 |
ts #2 / 13
|
 Array#sort! returns nil when array empty
M> Array#sort! returns nil if the array is empty pigeon% ruby -ve 'p [].sort!' ruby 1.7.1 (2001-07-03) [i686-linux] [] pigeon% pigeon% /usr/bin/ruby -ve 'p [].sort!' ruby 1.6.4 (2001-06-04) [i686-linux] nil pigeon% Guy Decoux
|
Mon, 29 Dec 2003 23:34:54 GMT |
|
 |
hful.. #3 / 13
|
 Array#sort! returns nil when array empty
Quote: > Array#sort! returns nil if the array is empty, whereas ri says it should > return itself: > arr.sort! -> arr
This is one of those features that I consider questionable. The idea is that a bang-method which *doesn't* change its receiver will return nil to show that the receiver is unchanged. The same happens in a case like "Hello".gsub!(/foo/,"bar") -- this returns nil also (I haven't tried it today :) though). What makes the feature even more questionable in my mind is that in the case of sort!, it only returns nil for the pathological cases like an array of length 0 or 1. It doesn't check arrays of arbitrary size. So even the inconsistency is inconsistent. Personally, I wouldn't mind seeing this feature removed... it always bites me when I chain methods, resulting in an error that "nil" doesn't have any such method. And I personally never use this feature -- i.e., I never check to see whether the receiver was really modified. I just assume that my postcondition holds. For example, if I use gsub! to remove commas from a string, I don't care that it didn't have any commas to begin with. I just know that after the gsub!, it definitely has no commas. Hal
|
Mon, 29 Dec 2003 23:44:29 GMT |
|
 |
hal9.. #4 / 13
|
 Array#sort! returns nil when array empty
Quote: > pigeon% ruby -ve 'p [].sort!' > ruby 1.7.1 (2001-07-03) [i686-linux] > [] > pigeon% > Guy Decoux
Ah, now *that* is interesting! What about other "bang" methods? Are they still the same? Hal
|
Mon, 29 Dec 2003 23:48:00 GMT |
|
 |
ts #5 / 13
|
 Array#sort! returns nil when array empty
h> What about other "bang" methods? Are they h> still the same? pigeon% ruby -ve 'p "a".gsub!(/c/, "")' ruby 1.7.1 (2001-07-03) [i686-linux] nil pigeon% Guy Decoux
|
Mon, 29 Dec 2003 23:53:27 GMT |
|
 |
ts #6 / 13
|
 Array#sort! returns nil when array empty
h> Personally, I wouldn't mind seeing this feature removed... it h> always bites me when I chain methods, resulting in an error h> that "nil" doesn't have any such method. This is the goal of the null pattern, but you can always write begin a.b.c.d.e.f.g.h.i rescue puts $! end and you don't execute the complete chain of methods Guy Decoux
|
Mon, 29 Dec 2003 23:50:12 GMT |
|
 |
Paul Branna #7 / 13
|
 Array#sort! returns nil when array empty
Quote: > And I personally never use this feature -- i.e., I never check > to see whether the receiver was really modified. I just assume > that my postcondition holds. For example, if I use gsub! to > remove commas from a string, I don't care that it didn't have > any commas to begin with. I just know that after the gsub!, it > definitely has no commas.
I almost agree. I don't like this feature, but I have used it. In an irc bot, I have the following function: def parse_args(str) arr = Array.new while str[0] != ?: if !(foo = str.slice!(/[^\s]+\s+/)) then # <-- take note arr.push(str) return arr end foo.strip! arr.push(foo) end str.slice!(1..-1) arr.push(str) return arr end This function takes a string of the form "a b c :d e f" and converts it to an array ["a", "b", "c", "d e f"]. Perhaps there is a better way to do this (I'm open to suggestions), but using the return value of slice! seemed like a really easy way to tell if there were no more whole words (i.e. someone left out the ":d e f"). On the other hand, the worst part about the bang functions working this way is that there is no good way to simulate the effect of using gsub vs. gsub!, i.e.: foo = "This is a test" foo.gsub!('foo','bar').gsub!(' ',"\t") does not work, but (foo.gsub!('foo','bar')||foo).gsub!(' ',"\t") does work, but is REALLY ugly. Perhaps, though chaining method calls together like this isn't really a good idea to begin with, and should be discouraged (since we are modifying the original string, the two method calls really are separate operations, and so should probably be on separate lines). Paul
|
Tue, 30 Dec 2003 00:09:35 GMT |
|
 |
ts #8 / 13
|
 Array#sort! returns nil when array empty
P> This function takes a string of the form "a b c :d e f" and converts it to P> an array ["a", "b", "c", "d e f"]. pigeon% ruby -e 'p ("a b c :d e f".split(/:(\S.*)|\s+/) - [""])' ["a", "b", "c", "d e f"] pigeon% but verify it :-) Guy Decoux
|
Tue, 30 Dec 2003 00:29:22 GMT |
|
 |
hal9.. #9 / 13
|
 Array#sort! returns nil when array empty
Quote: > foo = "This is a test" > foo.gsub!('foo','bar').gsub!(' ',"\t") > does not work, but > (foo.gsub!('foo','bar')||foo).gsub!(' ',"\t") > does work, but is REALLY ugly.
I'm now thinking that perhaps the "right" way to do this is: foo.gsub('foo','bar').gsub!(' ',"\t") i.e., the earlier chained methods are non-bang. I'll try this line of thought for a while. Hal
|
Tue, 30 Dec 2003 03:13:11 GMT |
|
 |
Paul Branna #10 / 13
|
 Array#sort! returns nil when array empty
Quote: > I'm now thinking that perhaps the "right" way to do this > is: > foo.gsub('foo','bar').gsub!(' ',"\t") > i.e., the earlier chained methods are non-bang. > I'll try this line of thought for a while. > Hal
Well, this does not achieve the desired result: foo = "This is a test" #=> "This is a test" foo.gsub('foo,'bar').gsub!(' ',"\t") #=> "This\tis\tb\ttest" foo #=> "This is a test" What we really want is: foo = "This is a test" #=> "This is a test" foo.gsub!('foo',bar') #=> nil foo.gsub!(' ',"\t") #=> "This\tis\ta\ttest" foo #=> "This\tis\ta\ttest" Paul
|
Tue, 30 Dec 2003 03:37:44 GMT |
|
 |
Paul Branna #11 / 13
|
 Array#sort! returns nil when array empty
Quote:
> pigeon% ruby -e 'p ("a b c :d e f".split(/:(\S.*)|\s+/) - [""])' > ["a", "b", "c", "d e f"] > pigeon%
Very cool! I really like regular expressions, but I am still very much an amateur. Paul
|
Tue, 30 Dec 2003 03:38:42 GMT |
|
 |
hal9.. #12 / 13
|
 Array#sort! returns nil when array empty
Quote: > > I'm now thinking that perhaps the "right" way to do this > > is:
[snip] Quote: > Well, this does not achieve the desired result:
[snip] Of course, Paul. Thank you. Another case of PBT (Posting Before Thinking). Thanks, Hal
|
Tue, 30 Dec 2003 04:03:19 GMT |
|
 |
Yukihiro Matsumo #13 / 13
|
 Array#sort! returns nil when array empty
Hi, In message "[ruby-talk:17733] Re: Array#sort! returns nil when array empty"
| |> pigeon% ruby -ve 'p [].sort!' |> ruby 1.7.1 (2001-07-03) [i686-linux] |> [] |What about other "bang" methods? Are they |still the same? reverse! always returns self too. Current behavior of "bang" methods is: (a) to provide the cheapest way to detect modification. (b) to discourage method chaining of "bang" methods, to avoid unnecessary surprises caused by object aliasing. Because it's hard to detect modification for "sort!" and "reverse" methods, they now return self always. And don't forget to avoid "bang" method chaining. In next major release, I plan to make non-bang methods as fast as bang methods in most of the cases (for non aliased objects), by using partial reference counting. matz.
|
Tue, 30 Dec 2003 07:32:26 GMT |
|
|