Re: [Boston.pm] something about @_ is different?

Ben Tilly via Boston-pm <[email protected]> Tue, 21 May 2019 16:18:34 -0700
Newsgroups gmane.comp.lang.perl.perl-mongers.boston
Message-ID <CANoac9UvZPXH5XaycF8jio2ySoeWWVk7NGixBCbQiewv8rAkyA@mail.gmail.com>
If you want to assign to all the individual elements in the passed in
array, you can.  Try this:

sub swapper {
    @_[0..$#_] = reverse @_;
}

That said, it is actually consistent.  It just doesn't match the mental
model that you had.

Perl is pass by reference, assign by value.  All else follows.

@_ starts off as an array of aliased elements.  But assign to @_, and
you've created a new array with new values.  Assign to the slots of @_, and
you've replaced the old values with new values in the original variables.
(That's the "pass by reference" bit.)  If you assign one value to another,
you copy the value.  If you then modify the second copy in place, the
original does not change.

The assignment by value is a shallow copy.  That means that when you copy a
reference, both copies point to the same underlying data.  Compare the
following:

my $foo = "Hello";
my $bar = $foo;  # Copies data
$bar .= ", World";
say($foo); # Prints "Hello\n"

my $foo = \"Hello";
my $bar = $foo; # Copies reference to same data
$$bar .= ", World";
say($$foo); # Prints "Hello, World\n"

It all follows logically.  And, modulo various optimizations, this is
exactly how it works under the hood.

On Tue, May 21, 2019 at 3:50 PM Greg London <email-2Ro/Dj86MvDSUeElwK9/[email protected]> wrote:

> Ugh. I dont like this.
>
> Its linguistically inconsistent.
> Assign to an element in array assigns back to caller var.
> Assign to whole array disconnects the aliases
> that ties @_ back to the caller vars and assigns to a local version of @_?
>
> If someone wants to disconnect the underlying aliases,
> call local() and put the syntactic sugar there.
>
> And then assigning to @_ without local() would work just
> like assigning to all the individual elements in array.
>
> Perl can be disappointing sometimes.
>
> Greg
>
>
>
> On Tue, May 21, 2019 2:12 pm, Conor Walsh wrote:
> > Assigning to @_ is weird and I don't recommend it. It's full of magic
> > aliases, which in some cases means you change the caller's variables,
> > which is usually not what you want.
> >
> > Check the beginning of perldoc perlsub.
> >
> >
> > On Tue, May 21, 2019, 2:04 PM Greg London <email-2Ro/Dj86MvDSUeElwK9/[email protected]> wrote:
> >
> >
> >>
> >> Hm, it could be a caffeine defficiency, but it seems that @_ is
> >> being treated different than other arrays.
> >>
> >> I can create a normal array:
> >> my @normal_array=('a','b');
> >>
> >> and I can assign an entirely new list to it:
> >> @normal_array=reverse(@normal_array);     # assign to array
> >>
> >>
> >> and I can assign to it in parenthesis an entirely new list
> >> (@normal_array)=reverse(@normal_array);   # assign to (array)
> >>
> >>
> >>
> >> And those assignements take hold as I would expect.
> >>
> >>
> >> When I use the exact same syntax for the @_ array instead
> >> of @normal_array, it doesn't work as expected: sub swapper{ (@_) =
> >> reverse(@_);  # this doesn't seem to do anything. }
> >>
> >>
> >> my @other=('x','y'); swapper(@other); print Dumper \@other;
> >>
> >> Pretty sure this code used to work,
> >> but that was many moons ago.
> >>
> >> Thoughts?
> >>
> >>
> >> Greg
> >>
> >>
> >> Here's the script in one big copy/paste block:
> >>
> >>
> >>
> >> my @normal_array=('a','b'); print "normal_array is "; print Dumper
> >> \@normal_array;
> >> @normal_array=reverse(@normal_array);     # assign to array
> >> print "normal_array is "; print Dumper \@normal_array;
> >> (@normal_array)=reverse(@normal_array);   # assign to (array)
> >> print "normal_array is "; print Dumper \@normal_array;
> >>
> >>
> >> sub swapper{ (@_) = reverse(@_);
> >> }
> >>
> >>
> >> my $one = "i am one"; my $two = "i am two";
> >>
> >> swapper($one,$two);
> >>
> >> warn "one is '$one'"; warn "two is '$two'";
> >>
> >> _______________________________________________
> >> Boston-pm mailing list
> >> [email protected]
> >> https://mail.pm.org/mailman/listinfo/boston-pm
> >>
> >>
> >
>
>
> --
>
> _______________________________________________
> Boston-pm mailing list
> [email protected]
> https://mail.pm.org/mailman/listinfo/boston-pm
>