Perl中使用哈希实现"闭包"

3
我希望将子程序作为哈希表的成员,并使其能够访问其他哈希表成员。
例如:
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
3个回答

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}->();

然而,这是一个奇怪的组合 -- 实质上,它是一个包含某些内置行为的数据结构。听起来很像对象。也许你应该考虑使用面向对象的方法来完成你的项目。

1
提前声明 $h 并将其赋值为哈希引用不是更简便吗?类似这样:my $h; $h = { msg => 'hello', express_yourself => sub { print $h->{msg}, "\n" } }; - MkV
是的,这非常类似于Class::Closure,它只需要一个AUTOLOAD来检查$self{$AUTOLOAD}是否为子例程并将其添加到包符号表中(假设setup()是类的构造函数)。 - MkV
这绝对是对象的作品。 - fengshaun

2

这将起作用:

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

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

0

关闭:

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

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接