gdo*_*ald 6 metaprogramming lvalue perl6 raku
我怎么知道使用时我是否真的需要返回l值FALLBACK?
我正在使用,return-rw但我只想return在可能的地方使用。我想跟踪我是否实际上已修改过%!attrs或仅在FALLBACK调用时读取了该值。
或者(替代方案B)我可以附加回调或类似的东西%!attrs来监视更改吗?
class Foo {
has %.attrs;
submethod BUILD { %!attrs{'bar'} = 'bar' }
# multi method FALLBACK(Str:D $name, *@rest) {
# say 'read-only';
# return %!attrs{$name} if %!attrs«$name»:exists;
# }
multi method FALLBACK(Str:D $name, *@rest) {
say 'read-write';
return-rw %!attrs{$name} if %!attrs«$name»:exists;
}
}
my $foo = Foo.new;
say $foo.bar;
$foo.bar = 'baz';
say $foo.bar;
Run Code Online (Sandbox Code Playgroud)
这感觉有点像XY问题,因此让我们简化示例,看看该答案是否对您的决策有所帮助。
首先:如果您在哈希中返回不存在的键的“值”,那么实际上您将返回一个容器,当分配给以下容器时,该容器将自动激活哈希中的键:
my %hash;
sub get($key) { return-rw %hash{$key} }
get("foo") = 42;
dd %hash; # Hash %hash = {:foo(42)}
Run Code Online (Sandbox Code Playgroud)
请注意,您需要在return-rw此处使用以确保返回实际的容器,而不仅仅是返回容器中的值。或者,您可以使用is raw特征,它允许您仅设置最后一个值:
my %hash;
sub get($key) is raw { %hash{$key} }
get("foo") = 42;
dd %hash; # Hash %hash = {:foo(42)}
Run Code Online (Sandbox Code Playgroud)
请注意,在这种情况下,请勿使用return,因为那样仍会再次去除容器内的污染物。
回到您的问题:
我想跟踪我是否实际上已修改过
%!attrs或仅在FALLBACK调用时读取了该值。
class Foo {
has %!attrs;
has %!unexpected;
method TWEAK() { %!attrs<bar> = 'bar' }
method FALLBACK(Str:D $name, *@rest) is raw {
if %!attrs{$name}:exists {
%!attrs{$name}
}
else {
%!unexpected{$name}++;
Any
}
}
}
Run Code Online (Sandbox Code Playgroud)
这将返回在哈希中找到的容器,或者记录对未知键的访问并返回一个不可变的Any。
关于计划B,记录更改:为此,您可以为此使用Proxy对象。
希望这对您的追求有所帮助。
| 归档时间: |
|
| 查看次数: |
98 次 |
| 最近记录: |