2010-06-15 65 views
3

我想有一个子例程作为一个哈希成员,它能够访问其他哈希成员。Perl,使用哈希“闭包”

例如

sub setup { 
    %a = (
    txt => "hello world", 
    print_hello => sub { 
    print ${txt}; 
    }) 
return %a 
} 

my %obj = setup(); 
$obj{print_hello}; 

理想的情况是输出 “Hello World” 的

编辑

对不起,我没有指定一个要求

我应该能够做到

$obj{txt} = "goodbye"; 

,然后$ OBJ {print_hello}应该输出goodbye

回答

7

如果你想调用代码能够修改消息在散列中,您需要通过引用返回散列。这样做你问什么:

use strict; 
use warnings; 

sub self_expressing_hash { 
    my %h; 
    %h = (
     msg    => "hello", 
     express_yourself => sub { print $h{msg}, "\n" }, 
    ); 
    return \%h; 
} 

my $h = self_expressing_hash(); 
$h->{express_yourself}->(); 

$h->{msg} = 'goodbye'; 
$h->{express_yourself}->(); 

然而,这是一个奇怪的药汁 - 本质上,它包含了一些内置行为的数据结构。听起来像一个对象给我。也许你应该为你的项目研究一种O-O方法。

+1

不会预先声明$ h,并且将hashref分配给它更简单?像我的$ h; $ h = {msg =>'hello',express_yourself => sub {print $ h - > {msg},“\ n”}}; – MkV 2010-06-15 14:15:22

+0

是的,这非常像Class :: Closure,它需要的是一个AUTOLOAD,它检查$ self {$ AUTOLOAD}是一个子引用并将其添加到包符号表(假定setup()是构造函数一类)。 – MkV 2010-06-15 14:16:49

+0

提及对象+1。这绝对是一个对象的工作。 – fengshaun 2010-06-15 23:13:49

2

这将工作:

sub setup { 
    my %a = (txt => "hello world"); 
    $a{print_hello} = sub { print $a{txt} }; 
    return %a; 
} 

my %obj = setup(); 
$obj{print_hello}->(); 
+0

感谢您的回复,请参阅编辑 – Mike 2010-06-15 13:30:24

0

关闭:

sub setup { 
    my %a = (
    txt => "hello world", 
    print_hello => sub { 
    print $a{txt}; 
    }); 
    return %a; 
} 

my %obj = setup(); 
$obj{print_hello}->(); 
+1

这是按书面形式工作,但会使'%a'成为一个全局变量。 – mob 2010-06-15 14:57:22