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

So, I have an array and a simple function that truncates 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 a display function. Why can't I just do this by assigning a function name, as it would be with built-in functions?

eg. You can do

 print map(length,@ar) 

but you cannot do

 print map(trim,@ar) 

you need to do something like:

 print map {trim($_)} @ar print map(trim($_),@ar) 
+4
source share
4 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 the prototype or immediately before the semicolon, you can use _ instead of $ : if this argument is not specified, $_ 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; 

By the way, do not use $a and $b outside the sort comparator: they are not protected from strict checks.

However, I prefer not to use prototypes for functions, which I write mainly because their use makes it difficult to mentally analyze the code. Therefore, I would prefer to use:

 map trim($_), @x; 

See also perldoc perlsub :

This is all very powerful, of course, and should only be used in moderation to make the world a better place.

+12
source

The prototype Sinan is talking about is the best way. But for earlier versions, the old standby mode still exists:

 sub trim { # v-- Here 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 many functions and it processes more arguments and list context, but also does not demonstrate this concept. A triple expression is a quick way to do what the prototype character "_" does.

... BTW, Perl rules!

+7
source

my favorite way to optionally use $ _ without the need for 5.10+ is as follows:

 sub trim { my ($s) = (@_, $_); $s =~ s/\s+$//; $s } 

this assigns the first element from @_ to $ s, if any, otherwise $ _ is used

+3
source

Many Perl built-in functions work on $ _ if no arguments are given.

If your function did the same, it would work:

 my @ar=("bla ", "ha 1"); sub trim { my $s=@ _?$_[0]:$_;$s =~ s/\s+$//; $s} print map(trim,@ar),"\n"; 

And yes, Perl is important.

-eight
source

All Articles