>Or DWIM "${\foo()}" to force scalar context.  Everytime I come across that
>construct I have to wonder why it's not called in scalar context.  The '$'
>would seem to imply it should.

Huh?  No more than 

    $x = scalar reverse fn();

would cause reverse() to call fn() in scalar context.  The reverse()
listop confers list context upon its right-hand operand(s).   Likewise,
so too does the \ listop confer list context upon its right-hand operand.


>I have to assume \foo() is actually \(foo()) or some such.  

I don't know what that means.  \foo() is \foo().  It's not any
different than \(foo()), and certainly not meriting an "actually".

IMHO, this is
>entirely non-intuitive.  Can anyone enlighten me as to why this is as it is?
>I believe there was a p5p discussion about this, but I dread delving into
>the archives again..

Try this, from the Third Camel('s old draft):

    As mentioned earlier, the backslash operator, although usually used
    on a single referent to generate a single reference, doesn't have
    to be.  When used on a list of referents, it produces a list of
    corresponding references.  The second line of both pairs of examples
    below does the same thing as the first line, but has the backslash
    automatically distributed throughout the whole list.

        @reflist = (\$s, \@a, \%h, \&f);     # List of four references
        @reflist = \($s,  @a   %h,  &f);     # Same thing

    If a parenthesized list contains exactly one array or hash, then all
    of its values are interpolated and references to each returned.

        @reflist = \(@x);                    # Interpolate array, then get refs
        @reflist = map { \$_ } @x;           # Same thing

    This also occurs when there are internal parentheses:

        @reflist = \(@x, (@y));            # But only single aggregates expand
        @reflist = (\@x, map { \$_ } @y);    # Same thing

    If you try this with a hash, the result will contain references
    to the values (as you'd expect), but references to I<copies>
    of the keys (as you might not expect).

    Since array and hash slices are really just lists, you can
    backslash a slice of either of these to get a list of references.
    Each of the next three lines does exactly the same thing.

        @envrefs = \@ENV{'HOME', 'TERM'};         # Backslashing a slice
        @envrefs = \( $ENV{HOME},  $ENV{TERM} );  # Backslashing a list
        @envrefs = ( \$ENV{HOME}, \$ENV{TERM} );  # A list of two references

    Since functions can return lists, you can apply a backslash to
    them.  If you have more than one function to call, first
    interpolate each function's return values into a larger list
    and then backslash the whole thing.

        @reflist = \fx();
        @reflist = map { \$_ } fx();                # Same thing

        @reflist = \( fx(), fy(), fz() );
        @reflist = ( \fx(), \fy(), \fz() );         # Same thing
        @reflist = map { \$_ } fx(), fy(), fz();    # Same thing

    The backslash operator always supplies a list context to its
    operand, so those functions are all called in list context.  If
    the backslash is itself in scalar context, you'll end up with
    a reference to the last value from the list returned by the
    function.

        @reflist = \localtime();      # Ref to each of nine time elements
        $lastref = \localtime();      # Ref to whether it's daylight savings time

    In this regard, the backslash behaves like the named Perl list
    operators, such as C<print>, C<reverse>, and C<sort>, which
    always supply a list context on their right no matter what might
    be happening on their left.  As with named list operators, use
    an explicit C<scalar> to force what follows into scalar context.

        $dateref = \scalar localtime();    # \"Sat Jul 16 11:42:18 2000"

--tom

Reply via email to