I have an array and a simple function that trims white spaces:
my @ar=("bla ", "ha 1")
sub trim { my $a = shift; $a =~ s/\s+$//; $a}
Now, I want to apply this to an array with the map function. Why can't I do this by just giving the function name like one would do with built-in functions?
For example, you can do
print map(length, @ar)
But you can't do
print map(trim, @ar)
You have to do something like:
print map {trim($_)} @ar
print map(trim($_), @ar)
If you are using 5.10 or later, you can specify _
as the prototype for trim
. If you are using earlier versions, use Axeman's answer:
As the last character of a prototype, or just before a semicolon, you can use
_
in place of$
: if this argument is not provided,$_
will be used instead.
use strict; use warnings;
my @x = ("bla ", "ha 1");
sub trim(_) { my ($x) = @_; $x =~ s!\s+$!!; $x }
print map trim, @x;
Incidentally, don't use $a
and $b
outside of a sort
comparator: They are immune from strict
checking.
However, I prefer not to use prototypes for functions I write mainly because their use makes it harder to mentally parse the code. So, I would prefer using:
map trim($_), @x;
See also perldoc perlsub:
This is all very powerful, of course, and should be used only in moderation to make the world a better place.
The prototype that Sinan talks about is the best current way. But for earlier versions, there is still the old standby:
sub trim {
# v-- Here's the quick way to do it.
my $str = @_ ? $_[0] : $_;
# That was it.
$str =~ s/^\s+|\s+$//;
return $str;
}
Of course, I have a trim
function with more features and handles more arguments and list context, but it doesn't demonstrate the concept as well. The ternary expression is a quick way to do what the '_' prototype character now does.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With