Beefy Boxes and Bandwidth Generously Provided by pair Networks
Come for the quick hacks, stay for the epiphanies.
 
PerlMonks  

Thoughts on the magicality of @_ and $_

by rinceWind (Monsignor)
on Jun 28, 2002 at 18:42 UTC ( [id://178095]=perlquestion: print w/replies, xml ) Need Help??

rinceWind has asked for the wisdom of the Perl Monks concerning the following question:

broquaint's recent reply to a discussion on programming style, has set me thinking.

So, if you want modifiable scalar parameters, you can change them inside a sub by using $_[0], $_[1] etc. as lvalues without resorting to references. Interesting.

Also, I am reminded of how $_ gets bound to successive members of an array:

foreach (@foo) { $_++; # Add 1 to each member of @foo }
Is the same true if you use an intermediate variable - does it get aliased, or merely assigned? Apologies: I don't have access to a machine running Perl at the moment
foreach my $bar (@foo) { $bar++; }
Also I'm wondering about the future of all this. What of behaviour in Perl 6? Coming back to the first scenario, I hear that Perl 6 will be getting some Ruby features. Does this include passing parameters by name and hence Jensen's device?

--rW

Note: magicality - this might be a new term I am coining. Magicality bears as much relation to magic as sexuality does to sex.

Replies are listed 'Best First'.
•Re: Thoughts on the magicality of @_ and $_
by merlyn (Sage) on Jun 28, 2002 at 20:32 UTC
    Is the same true if you use an intermediate variable - does it get aliased, or merely assigned?
    It's weirder than that. Check this out:
    my $one = "wired"; for my $two (grep 1, substr($one, 1, 3)) { sub { $_[0] = "eir" } -> ($two); } print $one;
    I'm using the lvalueness of the grep, foreach, substr, and argument passing there. With a little more work, you can add the lvalueness of slices and values as well. {grin}

    -- Randal L. Schwartz, Perl hacker

      More weirdness:
      my @l = 1..9; $_ = "foo" for grep $_ % 2, sort reverse @l; print "@l\n";
         MeowChow                                   
                     s aamecha.s a..a\u$&owag.print
Re: Thoughts on the magicality of @_ and $_
by erikharrison (Deacon) on Jun 28, 2002 at 19:21 UTC

    In answer to your first question, yes, named intermediate variables are in fact alises to the list elements (which means you need to watch for modifying constants).

    Second question. Yes, Perl 6 gets named parameters, and the ability to truly parse subs as builtins (except perhaps the current print FILEHANDLE LIST semantics). Check out the Apocylypses.

    Cheers,
    Erik

    Light a man a fire, he's warm for a day. Catch a man on fire, and he's warm for the rest of his life. - Terry Pratchet

    Update: Alright, my question doesn't quite answer your second question. I'm sorry, I got confused on what you meant by "pass by name". :-( I just sent a message asking for clarification to the Perl 6 language group.

      Yes, Perl 6 gets named parameters, and the ability to truly parse subs as builtins (except perhaps the current print FILEHANDLE LIST semantics).

      print FILEHANDLE LIST will be gone. FILEHANDLE.print(LIST) (or print FILEHANDLE : LIST) is the new syntax, as filehandles are objects.

      IFF I understand correctly.

      - Yes, I reinvent wheels.
      - Spam: Visit eurotraQ.
      

        We use a space where a comma is expected to disambiguate between several (slightly obscure) constructs. For example, indirect object notation. Of course, this is totally supportable with the lexical parsing rules changes (yum). However, the language doesn't seem to directly support user defined methods using this trick themselves.

        Cheers,
        Erik

        Light a man a fire, he's warm for a day. Catch a man on fire, and he's warm for the rest of his life. - Terry Pratchet

Re: Thoughts on the magicality of @_ and $_
by Aristotle (Chancellor) on Jun 28, 2002 at 19:49 UTC
    $ perl -e'my @foo=(1,2,3,4); for $bar (@foo) { $bar++ } print "@foo\n" +' 2 3 4 5
    Guess that answers the first part of your question. :)

    Makeshifts last the longest.

Re: Thoughts on the magicality of @_ and $_
by djantzen (Priest) on Jun 29, 2002 at 02:24 UTC

    So, if you want modifiable scalar parameters, you can change them inside a sub by using $_[0], $_1 etc. as lvalues without resorting to references. Interesting.

    Hehe, I have another word for it. I discovered this a couple of months ago and was really blown away because it means that even if you explicitly pass by value, there's no guarantee that your data won't be altered.

    Now despite a natural inclination toward "const correctness" (by which I mean maintaining control over what happens to one's data even when passing it by reference to other folk's functions), I've come to live with Perl's motto that you should keep people out of the living room by asking rather than by wielding a shotgun. But this seems like putting the TV right out in the front lawn. So, my question is why is this allowed? Is this a remnant from Perl 4? Will it be maintained in Perl 6?

      If you really, really need to, you can still force "const correctness", but like using closures to force total object data encapsulation, it takes extra effort for both the programmer and Perl.
      sub inc { $_[0]++ } my ($i,$j) = (0,0); inc(@{[$i]}); inc($j); print"$i $j\n";' =output 0 1
      ____________
      Makeshifts last the longest.
Re: Thoughts on the magicality of @_ and $_
by jarich (Curate) on Jul 01, 2002 at 04:17 UTC
    I used to always get bitten by this one:
    use strict; my $name; foreach $name (qw/alfred benjamin casey donald eugene/) { print "$name\n"; } print "*$name*\n";
    Of course this is simplified, but doesn't it seem like $name should be equal to "eugene" after the loop? But it isn't. It's undefined, because it was undefined at the start of the loop. So if you want to do something with the elements of the array and end up storing the last one as a side effect you have to do it in a similar way to this:
    use strict; my $name; foreach my $loopname (qw/alfred benjamin casey donald eugene/) { $name = $loopname; print "$name\n"; } print "*$name*\n";
    Which has never seemed as DWIMish as I wished for.

    ;)

    jarich

      I prefer it this way - in more traditional languages, I've actually been bitten by the existance of this side effect (or the desire to to use it cleverly). Not having this side effect may seem more awkward, but IMHO makes the code less kludgy and hackish.

      Makeshifts last the longest.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others learning in the Monastery: (3)
As of 2024-03-28 16:48 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found