in reply to Re^7: perlsub question..
in thread perlsub question..

Your statement :
@bar expands to a list of its elements, with anonymous undefined values in place of nonexistent elements
is negated by the code I posted.

No, it's not. In that post you treated @_ as an array and created new elements in it

sub x{ @_[3,4,5,6,8]=(3,4,5,6,939);show(@_)}
and expected that the new elements find their place in the original array, @y. Doesn't work, no way it could. Let's dissect that.
my @y;$y[3]=undef;

The array @y now has 4 elements, as perl -le 'my @y;$y[3]=undef;print scalar @y' confirms.

x(@y);

Now that is exactly the same as saying

x($y[0],$y[1],$y[2],$y[3]);

Then, in function x() you do

@_[3,4,5,6,8]=(3,4,5,6,939);

Are you expanding the parameter list after the fact of the subroutine call, or assigning to a different array? What do the docs say to that?

Any arguments passed in show up in the array @_. Therefore, if you called a function with two arguments, those would be stored in $_[0] and $_1. The array @_ is a local array, but its elements are aliases for the actual scalar parameters. In particular, if an element $_[0] is updated, the corresponding argument is updated (or an error occurs if it is not updatable). If an argument is an array or hash element which did not exist when the function was called, that element is created only when (and if) it is modified or a reference to it is taken. (Some earlier versions of Perl created the element whether or not the element was assigned to.) Assigning to the whole array @_ removes that aliasing, and does not update any arguments.

(emphasis mine) - assigning to the array slice @_ is also assigning to the array @_, it's just a special form.

Doing that you break the aliasing, and the elements you passed in (the elements of @y) stay as they were.

--shmem

_($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                              /\_¯/(q    /
----------------------------  \__(m.====·.(_("always off the crowd"))."·
");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}

Replies are listed 'Best First'.
Re^9: perlsub question..
by ysth (Canon) on Jun 24, 2007 at 22:53 UTC
    x(@y) is not exactly the same as saying x($y[0], $y[1], ...). It differs when one of the elements does not exist. That's the point of this subthread.

    And the documentation you cite does not apply; assigning to an array slice is not assigning to the array and does not remove the aliasing.

    Try it.

      Try it.

      I do and see

      #!/usr/bin/perl use strict; use warnings; use Data::Dump::Streamer; sub x { print "\@_ number of elements: ", scalar(@_),"\n"; ($_[0],$_[2]) = qw(foo bar); @_[3,4,5,6,8] = (3,4,5,6,939); bar(@_); } sub bar { print 'bar @_=(',join(',',map{"'$_'"} @_),")\n"; $_[3] = 'quux'; } my @y; $y[3] = undef; x(@y); Dump(\@y); __END__ @_ number of elements: 4 bar @_=('foo','','bar','3','4','5','6','','939') $ARRAY1 = [ ( undef ) x 3, 'quux' ];

      that you are right. Assigning to ($_[0],$_[2]) has effect to @_, but there are no aliases to something in @y.

      --shmem

      _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                    /\_¯/(q    /
      ----------------------------  \__(m.====·.(_("always off the crowd"))."·
      ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}