2009-12-01 166 views
4

所以我有一个数组和一个简单的函数,修剪空格:

my @ar=("bla ", "ha 1") 
sub trim { my $a=shift; $a =~ s/\s+$//; $a} 

现在,我想这个应用与地图功能的阵列。为什么我不能通过给函数名称来做这件事,就像用内置函数一样?

例如你可以做

print map(length,@ar) 

,但你不能做

print map(trim,@ar) 

你必须做的是这样的:如果给定的$ _

print map {trim($_)} @ar 
print map(trim($_),@ar) 
+0

在这些各种各样的情况,我问自己“我真的在乎如果我必须把它作为一个论点?“答案通常不是。有更好的事情要关心。 :) – 2009-12-02 20:33:30

+0

@brian - 你是对的 - 我只是想知道为什么行为是不同的 – naumcho 2009-12-02 21:14:50

回答

12

如果您使用5.10或更高版本,您可以指定_作为prototypetrim。如果您使用的是较早的版本,使用Axeman's answer

为原型的最后一个字符,或者只是一个分号之前,你可以代替$使用_:如果不提供这种说法,$_将使用代替。

use strict; use warnings; 

my @x = ("bla ", "ha 1"); 

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

print map trim, @x; 

顺便说一句,不要使用$a$bsort比较:他们是从免疫检查strict

但是,我不想因为它们的使用使得它更难精神分析代码,使用原型我写的主要功能。所以,我宁愿使用:

map trim($_), @x; 

perldoc perlsub参见:

这是非常强大的,当然,和应适可而止只是用来让世界变得更美好。

+0

'_'原型是否做了任何'my $ x = @_?转移:$ _'不会? – 2009-12-02 00:15:31

+0

@迈克尔卡尔曼:我不这么认为。但是,如果'trim'将在'$ _'上运行,如果没有参数提供,我宁愿使用原型而不是向'trim'添加额外的逻辑。最重要的是,我不会选择这种方式,只需要使用map trim($ _),@ x'。 – 2009-12-02 00:22:58

+0

@迈克尔卡曼:是的,它的工作原理与词汇$ _于呼叫 – ysth 2009-12-02 03:54:22

-8

许多Perl的内置函数没有操作参数。

如果你的功能也一样,它的工作:

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

是的,Perl是一种总值。

+4

如果你提供'trim'的适当原型,你就不必跳过那些箍环。 – 2009-12-02 00:04:51

+0

我同意;我学会了perl的原型。 – 2009-12-02 00:06:56

+2

不要在排序比较器外使用'$ a'。在条件运算符中不需要'scalar':'@_? $ _ [0]:$ _'。 – 2009-12-02 00:08:30

7

是思南谈论的是目前最好的办法原型。但对于早期版本,还有就是老待机:

sub trim { 
    # v-- Here's the quick way to do it. 
    my $str = @_ ? $_[0] : $_; 
    # That was it. 

    $str =~ s/^\s+|\s+$//; 
    return $str; 
} 

当然,我有一个trim功能与更多的功能和处理更多的参数和列表范围内,但它并没有说明这个概念也是如此。三元表达式是一个快速的方法做了“_”原型人物现在。

...顺便说一句,Perl的规则!

+0

真的很好的答案,因为我在5.8 - 谢谢* upvote *;尽管我不得不接受思南的最佳做法 - 我希望我能接受两者。 – naumcho 2009-12-02 21:26:07

3

我最喜欢的方式任意地使用$ _而不需要5。10+如下:

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

如此@_的第一个元素,如果有一个分配给$ S,否则使用$ _

相关问题