2015-05-14 137 views
0

我創建一個調度表的子程序參考:生成字符串中的

my $dispatch = { 
    'do_this' => \&do_this, 
    'do_that' => \&do_that, 
    'do_something' => \&do_something, 
    'do_something_else' => \&do_something_else, 
    }; 

而是在字符的鍵和值的相同的字符串類型的,我想這樣做:

my $dispatch_values = ['do_this', 'do_that', 'do_something', 'do_something_else']; 
my $dispatch = generate_dispatch_table($dispatch_values); 

sub generate_dispatch_table { 
    my $values = shift; 
    my $table = {}; 
    foreach $value (@$values) { 
    $table{$value} = #WHAT GOES HERE? 
    } 
    return $table; 
} 

雖然我不知道如何從字符串中生成子例程引用。

回答

4

只需使用\&{ $sub_name }

#! /usr/bin/perl 
use warnings; 
use strict; 

sub hi { print "Hi\n" } 
sub bye { print "Bye\n" } 

my %dispatch = map { $_, \&{$_} } qw(hi bye); 

chomp(my $action = <>); 
$dispatch{$action}->(); 
1

替代品包括:

  • 使用的對象。
  • 使用套餐。

對於一個對象,這幾乎是你習慣了什麼:

#! /usr/bin/perl 

package Foo; 
use warnings; 
use strict; 

sub hi { print "Hi\n" } 
sub bye { print "Bye\n" } 

sub new { bless {} } 

package main; 

my $dispatcher = Foo->new; 
chomp(my $action = <>); 
$dispatcher->$action(); 

當然,應該檢查是否can做的動作,但我們在這裏忽略了一些基本檢查。

另一個很好的檢查是不是如正在使用的動作,而是利用一個前綴,表示這是可分派的情況下,你必須在對象的其它非調度方法:

#! /usr/bin/perl 

package Foo; 
use warnings; 
use strict; 

sub do_hi { print "Hi\n" } 
sub do_bye { print "Bye\n" } 

sub new { bless {} } 

package main; 

my $dispatcher = Foo->new; 
chomp(my $action = <>); 
$action = "do_" . $action; 
$dispatcher->$action(); 

唯一的區別是do_前綴,但現在調用者不能通過調度程序調用new。否則,它是一樣的 - 這個調度員將像choroba的答案一樣調度hibye

請記住,當然,如果您傳遞參數,$self是第一個參數。

通過包這樣做幾乎是一樣的:

#! /usr/bin/perl 

package Foo; 
use warnings; 
use strict; 

sub do_hi { print "Hi\n" } 
sub do_bye { print "Bye\n" } 

package main; 

chomp(my $action = <>); 
$action = 'do_' . $action; 
Foo->$action(); 

在這裏,第一個參數是的,當然,「富」。我們也不需要一個對象,所以不需要構造函數。

但是,您可以將其直接應用於原始問題並避免一些額外的信號。只要刪除包裝聲明,並且即使在默認(主)包裝中也將Foo->$action()更改爲__PACKAGE__->$action()。但是,如果你不希望有包名傳遞中,我們採取這只是一個很小的一步:

sub do_hi { print "Hi\n" } 
sub do_bye { print "Bye\n" } 

chomp(my $action = <>); 
$action = 'do_' . $action; 
__PACKAGE__->can($action)->(); 

TMTOWTDI。選擇一個對你最有意義的代碼和你的代碼佈局。有時我會使用對象模型,有時候會使用另一個。