ZZamboni has asked for the wisdom of the Perl Monks concerning the following question:

Oh fellow monks, please enlighten me, for this has me stumped:
@a=('a', 'b', 'c'); print "test1: ".scalar(@a)."\n"; print "test2: ".scalar(sort @a)."\n";
When I run it with "perl -w t2.pl" I get:
test1: 3 Use of uninitialized value at t2.pl line 3. test2:
This is, when scalar is applied to the value returned by sort it returns undef. Does sort return something different in a scalar context? But then scalar should not be setting a scalar context, since its purpose is to get an array as argument.

What am I missing?

Thanks,

--ZZamboni

Replies are listed 'Best First'.
Re: scalar doesn't work values returned by a function?
by perlmonkey (Hermit) on May 10, 2000 at 06:49 UTC
    But scalar is setting scalar context, I believe that is its sole purpose in life. The sort function can look to see if the context it is being used is scalar or list via the function wantarray. It seems that sort returns undef in a scalar context:
    @a=('a', 'b', 'c'); $a = sort(@a); print $a; Use of uninitialized value at - line 3.
    To put sort into a list context there is no clean way to do it, (sort(@a)) doesnt do it in this case. But a snip from the perlfunc man pages for scalar says:
    There is no equivalent operator to force an expression to be interpolated in list context because it's in practice never needed. If you really wanted to do so, however, you could use the construction @{[ (some expression) ]}, but usually a simple (some expression) suffices.
    So this does work with -w (but it is a bit of extra work):
    @a=('a', 'b', 'c'); $a = @{[sort(@a)]}; print $a;
      You're right, but note that @{[ sort @a ]} evaluates as an array, not a list ($a would contain '3', not 'c').

      This is probably not a problem, since ZZamboni's code doesn't seem to want the last value from the sorted list. It is, however an entirely plausible reason to try:   (To get the last sorted value) scalar(sort @array)

      This is just a bit of a bummer, since it forces some kinda ugly syntax to do something which ZZamboni's code feels like it should just naturally do.

      my @a = ('a','b','c'); print ((sort @a)[$#a]);
      Russ
        You are correct, $a would equal 3 in my last bit of code, because the sort will return a list and then store it in a referenced array which is then dereferenced and cast into scalar context which finally returns the size of the array. Got it? Good.
        I dont think I implied anything else though. I am not under the impression that ZZamboni wanted anything other than the size of the sorted array, but maybe I am wrong.

        If you wanted the last element of the sorted array of course you would do (sort @a)[-1] I certainly would not guess that scalar(sort @a) would return the last element, so I am glad that it doesnt, but apparently you think it should. I suppose you could write your own sort routine to do that in scalar context, but I like it the way it is. Just my opinion though.
RE: scalar doesn't work values returned by a function?
by nuance (Hermit) on May 10, 2000 at 07:03 UTC
    Your problem stems from the fact that what is returned by the sort function is not an array, it is a list. The function scalar returns the number of elements in an array, but it does not work on general lists, only on arrays.

    Nuance

    Baldrick, you wouldn't see a subtle plan if it painted itself purple and danced naked on top of a harpsichord, singing "Subtle plans are here again!"

Re: scalar doesn't work values returned by a function?
by chromatic (Archbishop) on May 10, 2000 at 19:15 UTC
    What happens when you enforce scalar context on a compile-time-known list:
    my $number = scalar(1, 2, 3, 8, 16); print "Result: $number\n";
    Result: 16

    On an interpolated list:

    my $number = scalar (1 .. 10); print "Result: $number\n";
    Result: (yes, blank)

    perlfaq4 also says that there's no such thing as a list in scalar context.

RE: scalar doesn't work values returned by a function?
by merlyn (Sage) on May 10, 2000 at 23:41 UTC
    But then scalar should not be setting a scalar context, since its purpose is to get an array as argument.
    That's the part I don't understand you not understanding. The whole point of scalar is to create a scalar context. And sort has no scalar definition, so it's defined as undef for the moment.

    -- Randal L. Schwartz, Perl hacker