I need a subroutine that completely removes an array element in place. The following code fails:
sub del
{
splice(@_,2,1);
}
@array=(0..5);
print "@array"."\n";
del(@array);
print "@array"."\n";
The same array is printed again, i.e. the element has not been removed.
However, if I use the splice() in the main body of the program instead of calling a subroutine, it works.
While the scalar elements of
@_are aliased to the data which is passed in,@_itself is a different variable. This means$_[1] = "foo"will alter$_[1]butpush @_, "foo"will not alter@_. Otherwisemy $self = shiftwould be a Bad Thing.You need to pass in the array as a reference.
If you absolutely must keep the
del @arrayinterface, this is one of the few places where it’s appropriate to use a prototype.The
\@prototype tells Perl to pass in@arrayby reference. I would recommend against doing this for two reasons. First, prototypes have a pile of caveats which make them not worth the trouble.More importantly, it makes it non-obvious that
delwill modify its arguments. Normally user defined Perl functions copy their arguments, so you can look atfoo @arrayand be reasonably sure@arraywill not be altered byfoo. This enables one to skim the code quickly for things which will affect a variable. A reference prototype throws this out the window. Now every function must be examined for a possible hidden pass-by-reference.