in reply to Re^2: Prototype (_)?
in thread Prototype (_)?
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:
Here I used the prototype $, but _ of course works after \@, \%, + ... (but you can't have an unprototyped equivalent without using source filters)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 }
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:
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.sub unprototyped { goto &unprototyped @_, $_ unless @_ > 1; # See comments in previous exemples }
NB: for the '$_ is tied or should be modified' problem, an alias would work (but it is not core perl) but not this:
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.sub unprototyped { push @_, $_ if @_ < 2; # Do all the work $_ = $_[-1]; # Return value here }
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.
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^4: Prototype (_)?
by BrowserUk (Patriarch) on Dec 04, 2014 at 18:11 UTC |