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

You make a valid point(++), so I will modify my proposed behaviour statement to:

Elements of @_ are aliased to EXISTING or EXPLICITLY-passed element(s) of the passed parameter(s).
The sub may modify ONLY THESE elements. Attempts to modify othe elements will not be retained on sub exit.

     "An undefined problem has an infinite number of solutions." - Robert A. Humphrey         "If you're not part of the solution, you're part of the precipitate." - Henry J. Tillman

Replies are listed 'Best First'.
Re^6: perlsub question..
by ysth (Canon) on Jun 24, 2007 at 19:09 UTC
    You still seem to be thinking you can pass an array. "Existing elements of the passed parameters" only makes sense if you think foo(@bar) in some way passes @bar to foo. And it doesn't; @bar expands to a list of its elements, with anonymous undefined values in place of nonexistent elements. But I don't know that this behavior is set in stone, so I'd be reluctant to see it documented.
      This is precisely the mental model of parameter passing, that I'm trying to develop. Not the @arry passing part - - That's fine - you pass a list.

      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. If "nonexistent elements" were indeed passed, assigning values to the corresponding aliases would vivify, in the original array. This is not the case.

      The only elements that can get persistent new values from inside the sub are "existing" elements, or explicitly passed elements, as Jenda indicated.

      I agree that it would be crufty to take advantage of this in production code. I also think this behaviour is "correct", and sufficiently documented for most code, and can be persuaded that since the behaviour is subject to change, it should not be encouraged/documented. I'm just trying to understand what the behaviour is, and trying to ensure that I have not mis-understood it.

           "An undefined problem has an infinite number of solutions." - Robert A. Humphrey         "If you're not part of the solution, you're part of the precipitate." - Henry J. Tillman

        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. If "nonexistent elements" were indeed passed, assigning values to the corresponding aliases would vivify, in the original array. This is not the case.
        You misunderstood me. I said nonexistent elements are not passed, and that anonymous (i.e. not bound to the array in any way) undefined values are passed in their place.
        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}