in reply to Prototype (_)?

The idea is to recreate the effect of (say) how the length function is parsed:

#!perl -w use 5.010; sub mylength(_) { length($_[0]); }; for('a','aa','aaa') { say "length :", length; say "mylength :", mylength; say "mylength :", mylength($_); };

Replies are listed 'Best First'.
Re^2: Prototype (_)?
by BrowserUk (Patriarch) on Dec 04, 2014 at 12:30 UTC
    sub mylength(_) { length($_[0]); };

    Ah! So you use the positional form of the argument (ie. $_[n]) and if that position is unpopulated, perl supplies the value of $_.

    Got it. (Some mention of using $_[n] in the docs would be good :)


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.

      Well, as long as you don't change the value it would work the same with shift. Since you've had exemple already, and I'm not sure of what's troubling you, I'll try to answer a question you didn't ask: why? (or when?). In the best case, it'll help you, in a less optimal case, it'll help others, in the worst case scenario, someone will be able to correct one of my misconceptions :D

      In most case, the prototype _ as a simple prototype-less equivalent:

      sub prototyped($_;$) { # Here $_[0] is a compulsory argument # $_[1] defaults to $_ # $_[2] may not even exist } sub unprototyped { push @_, $_ if @_ < 2; # Here $_[0] is a compulsory argument # $_[1] defaults to $_ # $_[2] may not even exist }
      Here I used the prototype $, but _ of course works after \@, \%, + ... (but you can't have an unprototyped equivalent without using source filters)

      Now, that's probably enough in most cases, but this might cause some trouble if the function should modify its parameters (like chomp), or if $_ is a tied scalar (you'll call FETCH, which might have unexpected side effects) you can't just push a copy into @_. In this case, the best equivalent code I could come up with (using only core perl) is:

      sub unprototyped { goto &unprototyped @_, $_ unless @_ > 1; # See comments in previous exemples }
      Now that's where the _ becomes really useful, because not using goto will run faster, and will prevent people who can't tell the difference between the C-style and the other goto from calling you the devil.

      NB: for the '$_ is tied or should be modified' problem, an alias would work (but it is not core perl) but not this:

      sub unprototyped { push @_, $_ if @_ < 2; # Do all the work $_ = $_[-1]; # Return value here }
      Because in '# Do all the work', the modifications and copies of $_ won't trigger STORE and FETCH. A reference to either the parameter or $_ would work though, but it wouldn't be as transparent.

      And there is another case where push @_, $_ is not equivalent to the _ prototype, I'll leave this bit of code to show how _ can go wrong:

      use v5.14; sub f2 { while (<DATA>) { chomp; last; }; } sub f1(_) { f2; say shift; } f1 "Hello "; $_ = "World"; f1; f1 for "!"; __DATA__ Everyone Perlmonks

      Edit: of course, in all my exemples the user plays nice and never calls unprototyped without arguments.

        I wanted to write a sub that defaulted to operating upon $_ per chop, chomp and others.

        The problem I had was that I tried:

        sub x(_) { my $s = shift; ## make changes to $s ... }

        but in the calling code, $_ remained unmodified.

        As soon as I saw Corion's example above, it became obvious that when assigned to a named var, the named var held a copy rather than an alias; and that to achieve my goal, I would need to use $_[n]; just as with a normal subroutine: but not before seeing it. Silly perhaps, but ...

        I think the addition of a hint about aliasing or a short, working example would strengthen the documentation and perhaps save other people the same frustration.


        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
      Args are passed via @_. This is documented.