in reply to Reference to sort results

Whoa! my @sorted = sort @stuff; is right and easy. Where does this return \@sorted come from? Also possible is @stuff = sort @stuff;

Yes, it is possible to pass a reference to an array to be sorted like below, but why bother? You have a one line thing that sorts "stuff".

#!/usr/bin/perl -w use strict; my @a = (4,5,1,2); print "@a\n"; sort_ref_2_array (\@a); print "@a\n"; sub sort_ref_2_array { my $aref = shift; @$aref = sort @$aref; } __END__ prints: 4 5 1 2 1 2 4 5

Replies are listed 'Best First'.
Re^2: Reference to sort results
by Anonymous Monk on Aug 05, 2009 at 13:19 UTC
    Why bother? ...Because in reality I have an object containing a large hash, and I want one of its methods to return a sorted list of its values. More like:
    @sorted = sort { $a->{VAL} <=> $b->{VAL} } keys %bigHash; return \@sorted;
    Surely it is more efficient to return a reference to that list, as returning the array itself will involve creating a new copy of that array. If I use:
    return [ sort { $a->{VAL} <=> $b->{VAL} } keys %bigHash ];
    Will that duplicate the array, or just return a reference to the extant array? It isn't clear what perl does internally with this stuff. I'm just trying to be efficient, rather than throwing around big arrays willy-nilly.
      It's a reference to an anonymous array which is created in the same step as the return statement. Why would it duplicate it?

      Going from right to left:
      keys %bigHash
      generates a list, containing the values in the hash.
      sort {...}
      Manipulates the list according to the sort rule (sorts in ascending numerical order of the value associated with the key). Still a list.
      [...] #now the brackets
      the brackets tell Perl that "hey, this list in here? gimme a ref to an array with those elements in that order. This is the first point where it's an array in your example. It's unclear where you think copying an array is occurring. There's no practical difference between
      my @foo=sort @bar; return \@foo;
      and
      my $foo=[sort @bar]; return $foo;
      unless you try to manipulate the array in the subroutine, in which case you'd need to deal with @$foo in the second example. sort operates on a list and returns a list. If you use an array to feed it, it doesn't change the original array. The array you're worried about copying isn't an array yet at that point, so there's no risk of copying it.

      (And as a general note, if you aren't observing what appears to be a resource-driven slowdown, you should usually not try to out-think the language implementation, because in certain circumstances you can interfere with compiler-level optimization)

      Edit: I think perlreftut might provide some enlightenment.

        Thanks ssandv, that is really interesting. Could you tell me a little more?

        If I had an array, and wanted a reference to that exact same data, I would do this...

        $aref = \@array;

        Whereas, if I do this...

        $aref = [ @array ];

        ...Perl copies the contents of @array into a new anonymous array, then makes $aref a reference to the new one, right? So in this case @array and @$aref are entirely separate arrays.

        This is why I think:

        $aref = [ sort ... ];

        Would produce an array as the result of sort, copy that result into the new array implied by the brackets, give me a reference to the second array, and abandon the first one. It is not obvious whether Perl is smart enough to know that would be a waste of time.

        Furthermore, you say sort returns a list, not an array. As far as I am aware, Perl makes no explicit difference between the two, because its array data type can be used as an ordered list, so what do you mean by this?

        Thanks again for the help. I have been trawling the web but can't find anything which is clear on these points. I guess most people just don't worry about it!

Re^2: Reference to sort results
by Anonymous Monk on Aug 05, 2009 at 13:23 UTC
    Sorry: where I wrote "keys", I meant "values".