Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I make Perl functions that use $_ by default?

Tags:

perl

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)
like image 460
naumcho Avatar asked Dec 09 '22 18:12

naumcho


2 Answers

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.

like image 187
Sinan Ünür Avatar answered Jan 08 '23 16:01

Sinan Ünür


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.

like image 30
Axeman Avatar answered Jan 08 '23 17:01

Axeman