On Sat, Dec 13, 2003 at 11:04:57PM +0100, Stéphane Payrard wrote:
: On Sat, Dec 13, 2003 at 12:12:59PM -0800, Larry Wall wrote:
: > 
: >     print $ref
: > 
: > it doesn't do what you want, but
: > 
: >     print $ref.as(Array)
: > 
: > might work a lot better, though of course
: > 
: >     print @$ref
: > 
: 
: What is supposed to do the splat operator in this context?

Splat is a no-op in list context.  Its only use in an rvalue is
to introduce a list context where scalar context would normally
be inferred.  So you could say

    @args = ([EMAIL PROTECTED], 1, 2, 3);
    push [EMAIL PROTECTED];

even though push expects a scalar array ref as the first argument.

: My understanding is that when an operator expects something and gets
: a ref instead, the ref is dereferenced until the expected operand
: is found. The interpretor barks otherwise.

In scalar context, that's basically true.  (All ordinary scalars are
references anyway, which is why @_ is a call-by-reference array.)
In list context, however, a scalar variable provides a scalar value
by default.  It could be a scalar reference to the entire OED, but
Perl thinks it's a singular value, not a plural one, unless you tell
it otherwise somehow.

Actually, C<print> was a bad example, because $ref might well be
expanded (in a sense) by the stringification implicit to print.
Instead, let's consider:

    push @array, $ref;

That pushes a single reference into the array, because that is what
it looks like it's doing.  If you say

    push @array, $a, $b;

it doesn't matter whether $a or $b are references to arrays--it still
only pushes two singular values into the array.  In this case you
would have to say

    push @array, @$a, @$b;

to get the arrays flattened into the push's list argument.  (This is
just how it works in Perl 5 too.)

It would be possible to make the default the other way, and explicitly
mark where you *don't* want expansion, but I think it would be much
more error prone.  It would certainly make it more difficult to read
unfamiliar code and figure out what's going on.

: So I expect 
: 
:   print *$ref
: 
: when $ref is ref to an array to be equivalent to
: 
:   print [EMAIL PROTECTED]
: 
: which in turn should behave like
: 
:   print @$ref
: 
: because C<print> splats its operands.
: 
: I don't pretend that C<print *$ref> is very readable, I just ask
: what it does or if it is at all permitted.

It's permitted, but does nothing.  I admit that, to a C programmer, it
looks a bit like a deref, but this isn't C.  Perl has always derefed
arrays and hashes with @ and %, and that doesn't change in Perl 6.
All I'm saying above is that .as(Array) and .as(Hash) might have the
same result of explicitly dereferencing a singular reference to a
plural value.

Larry

Reply via email to