2009-12-01 220 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,否則使用$ _

相關問題