2010-02-03 51 views
4

你怎麼可以:如何在Perl中使用函數式樣進行編碼?

  1. sub回報sub

  2. 執行所文本代碼

在Perl

另外,我如何有一個匿名函數存儲狀態?

+4

重新運行代碼ad _高階Perl_。這是一本圍繞你的問題而建立的書。 – 2010-02-04 02:05:43

+1

鏈接:http://hop.perl.plover.com/雖然我確定Dominus讚賞實際購買的人 – ysth 2010-02-04 02:49:53

回答

16

一個子返回子作爲CODEREF

# example 1: return a sub that is defined inline. 
sub foo 
{ 
    return sub { 
     my $this = shift; 
     my @other_params = @_; 

     do_stuff(); 
     return $some_value; 
    }; 
} 

# example 2: return a sub that is defined elsewhere. 
sub bar 
{ 
    return \&foo; 
} 

任意文本可以與eval函數執行:請參閱文檔在perldoc -f eval

eval q{print "hello world!\n"}; 

注意,這是非常危險如果你正在評估從用戶輸入中提取的任何內容,並且通常是一個糟糕的練習,因爲通常可以用cod來定義你的代碼如前面的例子中所述。

可以存儲與state variable(新中perl5.10),或具有可變範圍的比子本身更高,作爲closure狀態:

use feature 'state'; 
sub baz 
{ 
    state $x; 
    return ++$x; 
} 

# create a new scope so that $y is not visible to other functions in this package 
{ 
    my $y; 
    sub quux 
    { 
     return ++$y; 
    } 
} 
+9

字符串'eval'幾乎總是一個糟糕的主意,強硬。唯一可以從頭腦中思考的地方就是要求一個帶有裸語義的模塊:'eval「需要$ module」;'。我知道還有一些其他的情況是有道理的,但我的觀點是它們很少。 – daotoad 2010-02-03 17:49:00

+2

絕對。初學者利用「eval」這個概念作爲錘擊所有的釘子,而實際上它是一種在罕見情況下最好保存在工具箱底部的工具。 – Ether 2010-02-03 17:51:45

+0

http://xkcd.com/327/ – 2010-02-03 23:32:01

7

返回的子程序參考。

下面是一個創建子裁判關閉了一個值一個簡單的例子:

my $add_5_to = add_x_to(5); 

print $add_5_to->(7), "\n"; 

sub add_x_to { 
    my $x = shift; 

    return sub { my $value = shift; return $x + $value; }; 

} 

您也可以使用名爲潛艇像這樣的工作:

sub op { 
    my $name = shift; 

    return $op eq 'add' ? \&add : sub {}; 
} 

sub add { 
    my $l = shift; 
    my $r = shift; 

    return $l + $r; 
} 

可以使用eval與任意的字符串,但不要這樣做。該代碼很難讀取,並重新開始編譯,這會減慢一切。有少數情況下,字符串評估是該工作的最佳工具。任何時候字符串eval似乎都是一個好主意,你用另一種方法幾乎肯定會更好。

幾乎所有你想用字符串評估做的事情都可以通過關閉實現。

5

使用sub關鍵字可輕鬆返回潛水艇。返回的子關閉它使用的詞彙變量:

#!/usr/bin/perl 

use strict; use warnings; 

sub mk_count_from_to { 
    my ($from, $to) = @_; 
    return sub { 
     return if $from > $to; 
     return $from ++; 
    }; 
} 

my $c = mk_count_from_to(-5, 5); 

while (defined(my $n = $c->())) { 
    print "$n\n"; 
} 

5.10介紹state variables

執行文本的Perl來完成使用eval EXPR

EXPR返回值被解析和執行,就好像它是一個小Perl程序。首先解析表達式的值(它本身在標量上下文中確定),如果沒有任何錯誤,則在當前Perl程序的詞彙上下文中執行,以便任何變量設置或子例程和格式定義在之後保留。需要注意的是價值被解析每次eval執行

執行任意的字符串開拓巨大巨大的安全漏洞。

5

您可以創建匿名子例程並通過引用訪問它們;這種參考當然可以被分配到一個標量:

my $subref = sub { ... code ... } 

或返回從另一個子程序

return sub { ... code ... } 

如果你需要存儲的狀態,您可以創建類似以下這樣的外部範圍定義的詞彙變量關閉:

sub create_func { 
    my $state; 
    return sub { ... code that can refer to $state ... } 
} 

您可以eval

相關問題