2009-10-25 44 views
3

想象一下這樣的子程序:如何正確調用帶2個子程序引用的子程序?

sub test(&&) 
{ 
    my $cr1 = shift; 
    my $cr2 = shift; 
    $cr1->(); 
    $cr2->(); 
} 

我知道我可以把它想:test(\&sub1,\&sub2),但我怎麼能這樣調用它:

test { print 1 },{ print 2 }; 

如果我說的子程序只需要一個&,比發送一個塊將工作。我不知道如何使它與2

工作,如果我嘗試這樣運行它,我得到:

Not enough arguments for main::test at script.pl line 38, near "}," 

編輯:有沒有調用沒有sub的方式嗎?

+2

爲什麼? (你想避免使用'sub'關鍵字) – Ether 2009-10-25 18:18:30

+0

我希望它看起來更'DSL'-ish。 – Geo 2009-10-25 18:25:44

+0

祝你好運與源過濾器,我猜:) – bdonlan 2009-10-25 18:27:59

回答

8

你可以這樣做:

test(sub { print 1 }, sub { print 2 }); 
+3

你_have_這樣做。否則,它會像你試圖傳遞兩個哈希引用一樣。 – innaM 2009-10-25 18:15:13

+0

我想不帶子地調用它們。兩個都。 – Geo 2009-10-25 18:15:22

+0

sub是Perl編寫匿名子程序的方式。因此,要麼使用ref作爲一個命名的子表達式,要麼使用一個表達式求值爲1(例如,其值爲子參數的變量),或者使用匿名子表達式 - 在後一種情況下,您將使用'sub {} – DVK 2009-10-25 18:17:19

1

我有下面的代碼在我的計劃之一:

sub generate($$$$) 
{ 
    my ($paramRef, $waypointCodeRef, $headerRef, 
     $debugCodeRef) = @_; 
... 
    &$headerRef(); 
... 
     my $used = &$waypointCodeRef(\%record); 

我叫它與

CreateDB::generate(\%param, \&wayPointCode, \&doHeader, \&debugCode); 
12

您需要明確地說

test(sub { print 1 }, sub { print 2 }); 

test { print 1 } sub { print 2 }; 

隱含 「子」 僅可用於第一個參數。 http://perldoc.perl.org/perlsub.html#Prototypes

一種&需要匿名的子程序,其中,如果作爲第一個參數傳遞,不需要的副關鍵字或隨後的逗號。

有些東西使用額外的字在那裏可以找到答案:

test { print 1 } against { print 2 }; 

sub against (&) { $_[0] } 
sub test (&@) { ... } 

,但我從來不喜歡那麼多。

+0

所以沒有'源過濾器'沒有辦法實現這個? – Geo 2009-10-25 18:17:56

+3

@Geo:僞裝源過濾器不存在。忘記你曾聽說過他們。 – ysth 2009-10-25 18:19:52

1

如果你真的想彎曲的語法更然後採取看看使用Devel::Declare模塊Devel::Declare

例子:

::申報可以通過 CPANTS

在這裏找到的modules on CPAN dependant對devel

完整列表例如,從Test::Class::Sugar pod

use Test::Class::Sugar; 

testclass exercises Person { 
    # Test::Most has been magically included 

    startup >> 1 { 
     use_ok $test->subject; 
    } 

    test autonaming { 
     is ref($test), 'Test::Person'; 
    } 

    test the naming of parts { 
     is $test->current_method, 'test_the_naming_of_parts'; 
    } 

    test multiple assertions >> 2 { 
     is ref($test), 'Test::Person'; 
     is $test->current_method, 'test_multiple_assertions'; 
    } 
} 

Test::Class->runtests; 


這裏是從PerlX::MethodCallWithBlock pod東西性感:

use PerlX::MethodCallWithBlock; 

Foo->bar(1, 2, 3) { 
    say "and a block"; 
}; 


Devel :: Declare是一個多mor與使用像Filter::Simple這樣的源代碼過濾器相比,這是一種穩健和更加健全的扭曲Perl代碼的方式。

這是一個video從它的作者,這可能會幫助更多。

/I3az/

+0

是什麼使這項工作?源過濾器? – Geo 2009-10-26 10:56:51

+0

來自Devel :: Declare文檔:「Devel :: Declare可以安裝稱爲聲明器的子例程,它在本地接管Perl的解析器,允許創建新的語法。」我真的不明白它是如何工作的,但它不是一個源過濾器。 – 2009-10-26 13:07:09