是否可以在Perl中的哈希构造函数中定义匿名子例程?
我正在尝试做这样的事情:
my %array = { one => sub { print "first $_[0]" },
two => sub { print "next $_[0]" },
three => sub { print "last $_[0]" }};
$array{$foo}->('thing');
但它不起作用。代码似乎运行和编译,但数组中的值是空白的。如果我这样做:
my %array;
$array{'one'} = sub { print "first $_[0]" };
$array{'two'} = sub { print "next $_[0]" };
$array{'three'} = sub { print "last $_[0]" };
$array{$foo}->('thing');
然后它似乎工作正常。所以我有一个解决方法,但它只是困扰我,我想知道是否有人知道它是否可能,如果是,那么语法是什么。
答案 0 :(得分:11)
看起来你错误地分配了哈希值。使用{}
构造一个匿名哈希引用,您可以将其指定给标量。但是你要分配一个命名的哈希(%array
)。
你需要分配一个标量:
my $array = { one => sub { print "first $_[0]" },
two => sub { print "next $_[0]" },
three => sub { print "last $_[0]" }};
$array->{$foo}->('thing');
或者不使用匿名构造函数语法:
my %array = ( one => sub { print "first $_[0]" },
two => sub { print "next $_[0]" },
three => sub { print "last $_[0]" });
$array{$foo}->('thing');
答案 1 :(得分:6)
那是因为在第一种情况下,你创建一个hashref而不是一个hash,你想要的是:
my $array;
$array = { one => ... }; # not %array = { .. };
...
$array->{one}->('thing');
答案 2 :(得分:4)
strict
编译指示。此外,始终启用警告 - 但我建议不要在代码中使用-w开关。
相反,请利用use warnings
pragma。这样,您可以选择性地禁用代码的词法范围区域中的特定警告组。
例如:
use strict;
use warnings;
foo('bar');
foo();
sub foo {
no warnings 'uninitialized';
my $foo = shift || 'DEFAULT';
print "Foo is $foo\n";
}
一致使用严格和警告的pragma将为您节省数小时的时间。
答案 3 :(得分:3)
我花了两个小时试图在不久前在脚本中追踪这个exact braces-vs-parentheses problem。如果您使用-w
切换到Perl,那么您将收到一条警告“参考找到了偶数大小的列表预期”,这至少可以提供一个线索。今天,所有Perl脚本都应该以:
#!/usr/bin/perl -w
use strict;
你的Perl生活将变得不那么令人沮丧。
答案 4 :(得分:2)
它应该是括号,而不是花括号:
my %array = ( one => sub { print "first $_[0]" },
two => sub { print "next $_[0]" },
three => sub { print "last $_[0]" }});
'{a => 1,b => 2}'生成对哈希的引用。所以以下内容也有效:
my $array = { one => sub { print "first $_[0]" },
two => sub { print "next $_[0]" },
three => sub { print "last $_[0]" }};
$array->{one}->('thing');