Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

Re^2: Accessing Arguments inside Subroutines via @_

by LanX (Saint)
on Mar 21, 2015 at 12:43 UTC ( [id://1120837]=note: print w/replies, xml ) Need Help??


in reply to Re: Accessing Arguments inside Subroutines via @_
in thread Accessing Arguments inside Subroutines via @_

I think what is really troubling you is the ambiguity between setting a symbol's slot and assigning to a symbol in Perl. (not sure if this is proper terminology)

Pure Perl has neither an explicit alias operator, nor an explicit unalias operator.²

So if a scalar variable $a is an alias to $b you can't easily say $a=42 without changing $b , i.e. replacing the alias in the $a -"slot" with a literal 42.¹

But when operating with arrays like @_ you have the choice.

$_[0]=42 is accessing the alias behind, but @_=(42) will replace the content of the slot.

DB<106> sub repl { @_=(42); print "> $_[0]"; } DB<107> $a=666 => 666 DB<108> repl $a > 42 DB<109> $a => 666

It has already been shown how to access multiple aliases at once (slicing), similarly you can use splice to access multiple slots of an array at once.

I hope the distinction between setting a slot and assigning to an alias is clearer now. :)

Cheers Rolf
(addicted to the Perl Programming Language and ☆☆☆☆ :)

PS: Je suis Charlie!

¹) But you can always use my $a=42 in a new scope or local $a=42 if it's a package var.

²) like tie and untie

Replies are listed 'Best First'.
Re^3: Accessing Arguments inside Subroutines via @_
by Athanasius (Archbishop) on Mar 22, 2015 at 09:04 UTC

    Hello LanX,

    I think what is really troubling you is the ambiguity between setting a symbol's slot and assigning to a symbol in Perl.

    I’m not sure if I understand the distinction you’re making here, but my current understanding of a Perl alias is that it’s in some ways analogous to a smart pointer. That is, it has its own identity as a scalar value (of type “alias”), but under certain conditions it behaves “transparently” as the entity it aliases, like a dereferenced pointer. To explain what I mean: I was experimenting with various permutations of the following code:

    and the output shows that following unshift @_ the element $_[1] is now an alias for the first argument. So, when explaining how @_ functions in a subroutine, I would no longer say “$_[0] is an alias for the first argument,” but rather “$_[0] is initialised to a (scalar value which is an) alias for the first argument.”

    And the difference in behaviour between, e.g., @_ = reverse @_ and ( $_[0], $_[1] ) = ( $_[1], $_[0] ), comes down to whether the aliases act “transparently” or ”opaquely.” When elements of @_ are accessed individually — whether singly or as part of an array slice — they behave “transparently,” but when the array @_ is assigned-to — via = or splice — its alias values are accessed “opaquely,” meaning their referents remain unaffected.

    Well, that’s my current understanding, and it may be just a convoluted way of repeating your explanation in different words. Anyway, I think I now understand what’s going on a little better than I did before. :-)

    Update: Fixed typo.

    Thanks for the help,

    Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

      Well you asked for the "why" not for the "how" ... :)

      I took a look into the Panther book and experimented with Devel::Peek and the implementation of aliases seems simpler than a magic data structure of type alias.

      Arrays (AVs) are composed from C-structures with pointers to C-structure(s) realizing scalars (SVs).

      So $_[0]=666 updates the underlying scalar ( what I called "assigning" ) while @_=(666) creates the pointer to a new scalar ( "setting" ).

      In the following dump the scalar value for $x is held within SV = IV(0x88f2498) at 0x88f249c

      The array's first slot will point to that same structure before and after updating with $_[0]=666 (#markers added)

      But creating new entries with @_=(666) will replace the pointer in this AV-slot to a new SV.

      I hope the "how" is clearer now! :)

      Cheers Rolf
      (addicted to the Perl Programming Language and ☆☆☆☆ :)

      PS: Je suis Charlie!

Re^3: Accessing Arguments inside Subroutines via @_
by AppleFritter (Vicar) on Mar 21, 2015 at 16:59 UTC

    Pure Perl has neither an explicit alias operator

    You can (ab)use typeglobs for this, at least for package variables. For instance:

    #!/usr/bin/perl no strict; use warnings; use feature qw/say/; $a = 42; *b = *a; say $b; # 42 $b = 69; say $a; # 69

    I can't think of a way of doing this with lexicals off the top of my head, though.

    nor an explicit unalias operator.²

    So if a scalar variable $a is an alias to $b you can't easily say $a=42 without changing $b , i.e. replacing the alias in the $a -"slot" with a literal 42.¹

    I don't think this is needed. Suppose that you have variables - let's say lexicals - $a and $b, with the latter being aliased to the former. Unalias $a would mean creating a new lexical that's not related to $b anymore, so why not just declare a new lexical with the same value (my $c = $b) and use that instead? The result's the same, and it's arguably clearer, since if you look at any line in isolation there's no confusion over whether $a is (still) aliased to $b anymore.

    OTOH there's something to be said in favor of explicit alias and unalias operators as well. I'd not be surprised at all if there were CPAN modules that implemented this.

      I just wanted to highlight why it makes sense that assigning to @_ doesn't write thru to the aliases.

      my and local were already mentioned in my footnote, when using typeglobs I'd strongly suggest to prefer *b = \$a; over  *b = *a;

      But these mechanisms are no big help if you want named parameters in subs cause those are lexicals, (which should be the preferred variable flavor).

      > I'd not be surprised at all if there were CPAN modules that implemented this.

      see Data::Alias or Lexical::Alias and their discussion in PBP

      Perl6 aims to handle aliasing consistently.

      Cheers Rolf
      (addicted to the Perl Programming Language and ☆☆☆☆ :)

      PS: Je suis Charlie!

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1120837]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others contemplating the Monastery: (5)
As of 2024-04-26 08:33 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found