我正在声明一个哈希,并且在声明它的时候,我在内部将其用于其中一个元素作为其他元素的输入。您可以通过遵循严格编译指示为ON的未编译代码轻松掌握:
my %cob = (
'a' => 0,
'b' => 0,
'z' => sub {
my ($a, $b) = ($cob{'a'}, $cob{'b'});
return ($a+$b+1);
}
);
及其产生的编译时错误。
所以我的问题是,如何在声明时重用相同的哈希元素作为对相同哈希的其他元素的输入?这里的元素“ a”和“ b”是“ z”元素函数的输入。
逻辑上,如果尚未声明哈希,则不能使用它,因此如何在声明时使用一个元素作为相同哈希的另一元素的输入?希望我很清楚...
答案 0 :(得分:4)
考虑在lexical closure内创建共享的$aa
和$bb
变量以生成新的穗轴哈希。
sub make_cob {
my($aa,$bb) = (0, 0);
{ a => \$aa,
b => \$bb,
z => sub { $aa + $bb + 1 },
};
}
如果需要在$aa
中进行任何排序,则变量名$bb
和make_cob
会在perlvar documentation on $a
and $b
中避免出现警告:
$a
$b
使用sort时的特殊程序包变量。由于这种特殊性,即使使用use vars
也不需要声明$a
和$b
(使用our
或strict 'vars'
pragma)。如果您希望能够在sort比较块或函数中使用它们,请不要使用my $a
或my $b
来词汇化它们。
将其中一个用作普通哈希%cob
my %cob = %{ make_cob() };
${$cob{a}} = 10;
${$cob{b}} = 20;
print "z: ", $cob{z}(), "\n";
作为哈希引用$cob
,代码为
my $cob = make_cob;
${$cob->{a}} = 30;
${$cob->{b}} = 40;
print "z: ", $cob->{z}(), "\n";
您可以将它们全部包装在匿名子中,如
sub make_cob {
my($aa,$bb) = (0, 0);
{ a => sub { if (@_) { $aa = shift } else { $aa } },
b => sub { if (@_) { $bb = shift } else { $bb } },
z => sub { $aa + $bb + 1 },
};
}
my $cob = make_cob;
$cob->{a}(40);
$cob->{b}(50);
print "a: ", $cob->{a}(), "\n",
"b: ", $cob->{b}(), "\n",
"z: ", $cob->{z}(), "\n";
但是如果您要解决所有麻烦,请使您的Cobs实例成为Cob类。
package Cob;
use strict;
use warnings;
sub new {
my($class,$aa,$bb) = @_;
$_ = defined $_ ? $_ : 0 for $aa, $bb;
bless { a => $aa, b => $bb } => $class;
}
sub a { $_[0]->{a} }
sub b { $_[0]->{b} }
sub z { $_[0]->a + $_[0]->b + 1 }
1;
使用此课程进行锻炼
#! /usr/bin/env perl
use strict;
use warnings;
use Cob;
my $cob = Cob->new(1,2);
print "a: ", $cob->a, "\n",
"b: ", $cob->b, "\n",
"z: ", $cob->z, "\n";
输出:
a: 1 b: 2 z: 4
答案 1 :(得分:2)
my ($a, $b) = ($cob{'a'}, $cob{'b'});
为了使Perl compile 此语句,必须在该语句之前的某个位置声明%cob
,但尚未声明%cob
(因为它是其中的一部分)该声明)。解决方案是在语句前声明%cob
:
my %cob; # declare the variable first
%cob = (
'a' => 0,
'b' => 0,
'z' => sub {
my ($a, $b) = ($cob{'a'}, $cob{'b'}); # now %cob is known to be a hash
return ($a+$b+1);
}
);