Array#sort! returns nil when array empty 
Author Message
 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  
 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  
 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  
 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  
 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  
 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  
 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  
 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  
 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  
 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  
 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  
 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  
 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  
 
 [ 13 post ] 

 Relevant Pages 

1. Regex Groups in String#split (Re: Array#sort! returns nil when array empty)

2. empty Array returned but expect nil

3. empty file returns nil not empty string?

4. Array.uniq! returning nil

5. Array.new returns nil

6. return value maxloc of an empty array!?

7. Array#push(empty array expanded) => no exception

8. java array return value not array in tcl

9. Problem with with Array of U8 to Array of Array of Boolean

10. convert 2d array to 1d array without using shift registers and build array

11. Arrays: Build array in multiple for loops or replace array elements

12. Multidimensional array vs. array of array

 

 
Powered by phpBB® Forum Software