I have told my co-workers many times that using shift when getting args to a sub is what they should be doing:
sub foo {
my $zog = shift;
....
}
instead of:
sub foo {
my $zog = $_[0];
....
}
Because no one re-uses @_, and I don't think most understand how @_ really works. Do people listen? No. Well, some did when I explained how it copies data from @_ needlessly in their code. But, it is still used.
So, today I was debugging some taint errors being throws by a CPAN module, and tracked it down to an internal module. It calls an AUTOLOAD'd method on the CPAN module, which in turn uses @_. If @_ exists, the autoloaded method returns 1, otherwise 0. But, since @_ isn't altered in the calling method, it ALWAYS returns 1 (making it useless) and becomes taint-unsafe since the autoloading tries to eval on the value from @_.
So kids, when someone explains to you that one thing isn't as good as another, please listen! It could save time from fixing broken code in the future.
Curiously, Ben Tilly mentioned that at least one company would ding you on a code review for using shift.
Don't you think that you've just found a special case? Unless I misunderstood you, you would dislike the following:
my ($self,$user,$pass,$action) = @_;For the that example, it seems clearer to use @_ rather than shift four times. It's clean and concise, though one might argue about the interface.
my ($class, @args) = @_;How would you recommend using shift for that? It's a common idiom and again it's fairly clear. It seems to me that you found an unusual situation where you were bit by @_ not being cleared, but that seems like a bug in the author's code and not necessarily a bad programming practice. Admittedly, you now have the data duplicated in the sub, but unless someone is being stupid and passing huge argument lists, this doesn't seem like such a a problem (unless someone uses the above and then tries to diddle with @_, at which point they deserve their grief).
I guess this is all a long-winded way of saying that I must be misunderstanding you.
Re:Always use shift?
KM on 2002-11-19T21:33:47
No misunderstanding... I like shift. It's sort of like using warnings and strict.. helps protect you from stupid things that can occur (like this situation, copying large parts of data, inadvertandly having @_ diddled with unexpectedly, etc...) Also, I read code vertically, not horizontally (when scanning code), so 4 or more vertical shifts is better to me than many linear variables.Most things I write lately uses named params anyways. So there is only 1 or 2 shifts (2 if it is an object, for $self and the args). This is simply more scalable and maintainable (in my opinion).
So, I like shift and will continue to use it unless there is a compelling (or code-wise) reason not to.
Re:Always use shift?
Ovid on 2002-11-19T21:51:14
KM wrote: Most things I write lately uses named params anyways.
Hmm... perhaps you might be the target audience for what is arguably my most useless module (Sub::NamedParams).
Of course, if I ever get the courage to upload Acme::Code::Police, then that will qualify as my most useless module. I've been hesitant to do so due to potential hate mail -- not to mention lawsuits
:) Re:Always use shift?
KM on 2002-11-19T22:13:25
Hmmm... looks like simply passing a hashref is easier than adding a module to pass a hashref:) But, maybe I'll take a closer peek. I tend to not like using modules to do things which are easy to do without them. I still have to upload my Acme::ReturnOne and Acme::ReturnZero to be the two most useless CPAN modules.... EVER!!