在EVAL中绑定哈希时,遇到了一些我不了解的问题。将哈希绑定到EVAL之外可以正常工作。EVAL中的未绑定哈希按预期工作。但是,将散列绑定到EVAL中无法正常工作。(我的期望可能是错误的。)下面是代码:
这有效:
#!/usr/bin/env raku
class Hash::Test does Associative {
has %.hash;
multi method STORE(@pairs) {
for @pairs -> $pair {
self.STORE: $pair
}
}
multi method STORE(Pair $pair) {
%!hash{$pair.key} = $pair.value;
}
}
no strict;
%hash-test := Hash::Test.new;
%hash-test = foo => 'bar', baz => 'quux';
say %hash-test;
输出:
$ ./hash-binding-works.raku
Hash::Test.new(hash => {:baz("quux"), :foo("bar")})
这有效:
#!/usr/bin/env raku
class Foo {
use MONKEY-SEE-NO-EVAL;
method eval(Str $code) {
EVAL $code;
}
}
my $code = q:to/END/;
no strict;
%hash = foo => 'bar', baz => 'quux';
END
Foo.eval: $code;
say %Foo::hash;
输出:
$ ./hash-EVAL-works.raku
{baz => quux, foo => bar}
但这不起作用:
#!/usr/bin/env raku
class Hash::Test does Associative {
has %.hash;
multi method STORE(@pairs) {
for @pairs -> $pair {
self.STORE: $pair
}
}
multi method STORE(Pair $pair) {
%!hash{$pair.key} = $pair.value;
}
}
class Foo {
use MONKEY-SEE-NO-EVAL;
method eval(Str $code) {
EVAL $code;
}
}
my $code = q:to/END/;
no strict;
%hash-test := Hash::Test.new;
%hash-test = foo => 'bar', baz => 'quux';
say %hash-test;
END
no strict;
Foo.eval: $code;
say %Foo::hash-test;
输出:
$ ./hash-EVAL-does-not-work.raku
Hash::Test.new(hash => {:baz("quux"), :foo("bar")})
{}
Hash :: Test不是我正在使用的真正的课程,而是我追求的目标。谁能解释这是怎么回事?谢谢!
TL; DR 通过隐式声明no strict;
符自动声明包变量。通过隐式词法变量声明符声明包变量,该声明符绑定到具有相同名称的隐式包符号。您的代码破坏了绑定,这也破坏了您的代码。要解决此问题,请用另一种方式说同样的话。our
our
my
no strict;
无济于事,所以我们摆脱了这一点。同样适用our
。取而代之的是,我们声明一个my
词法变量,用它来做我们需要做的/可以做的一切,然后在将要生成的EVAL
d的代码结尾处,创建一个包变量并将其绑定到词法中存储的值。
my $code = q:to/END/;
my %hash is Hash::Test;
%hash = foo => 'bar', baz => 'quux';
OUR::<%hash-test> := %hash;
END
Foo.eval: $code;
say %Foo::hash-test; # Hash::Test.new(hash => {:baz("quux"), :foo("bar")})
在no strict;
隐式声明our
变量下没有显式声明符的情况下声明的变量:
no strict;
%hash-test = :a;
say MY::<%hash-test>; # {a => True}
say OUR::<%hash-test>; # {a => True}
换句话说,仅上述前两行的净效果等同于:
our %hash-test = :a;
反过来,our
变量隐式声明my
变量,并遵循此SO中显示的逻辑。所以这段代码:
no script;
%hash-test := ...;
正在这样做:
(my %hash-test := $?PACKAGE.WHO<%hash-test>) := ...;
它会创建一个词汇 %hash-test
符号和一个包 %hash-test
符号,并将它们绑定在一起(该绑定对于our
变量的正常运行必不可少),然后立即中断该基本绑定。
此后,无论代码的其余部分做什么,它只会对变量的词法 %hash-test
版本执行此操作,而使软件包符号版本保持%hash-test
高位和干燥状态,以便稍后将其自动保存为空散列。
正如jnthn在SO下方的评论中所说,我一开始就链接了:
我们当然可以警告说,绑定到
our
变量是没有意义的
但是目前没有警告。
正如您在下面的评论中所解释的那样,当您尝试使用%hash-test is Hash::Test
编译器时,神秘地决定您已编写了“连续两个术语”。正如我在评论中所解释的那样,这是由于our
使用普通语法(或使用隐式no strict;
)声明变量时,上述原因所致。
要解决以上所有问题,请忘记no strict;
,忘记使用和our
,而是:
使用词汇来完成设置值的工作;
通过创建带有的包符号OUR::<%hash-test>
并将其绑定到词法的值来结束。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句