为什么可以修改 Raku class 上的只读数组属性?
Why can readonly array attributes on a Raku class be modified?
为什么只读数组属性可以在 Raku 上修改 class,而另一方面,标量不能修改?
如何让@.baz
“只读”?
class Boo {
has $.bar;
has @.baz;
};
my $boo = Boo.new;
$boo.baz = (1, 2); # works ... ?
say $boo.baz;
$boo.bar = 1; #fails ... expected
我的落语版本:
This is Rakudo version 2020.05.1 built on MoarVM version 2020.05
implementing Raku 6.d.
baz
属性是只读的。
问题是 baz
属性是一个 Array
具有可变元素。
当您调用 $boo.baz
时,您基本上得到了对数组的引用。
一旦您获得了对数组的引用,您就可以执行您通常可以对该数组执行的任何操作。
say $boo.baz.VAR.name; # @!baz
当你赋值给一个数组时,你实际上是在告诉数组它将有新的内容。
my @a = ('a','b','c');
say @a.WHICH; # Array|94070988080608
@a = (1, 2, 3);
say @a.WHICH; # Array|94070988080608
请注意 .WHICH
没有改变。那是因为它仍然是同一个数组。它只是有新的内容。
当您分配给 public 数组属性时,会发生完全相同的事情。
您不是在分配新数组,而是在更改现有数组。
变量的所有行为都不是变量固有的,它们是由对象处理的。
在数组的情况下,处理分配的对象是 Array
.
最简单的修复方法是重载自动生成的访问器方法。
class Boo {
has $.bar;
has @.baz;
method baz () { @!baz.List }
}
如果您从不打算更改 @!baz 中的值,您可以将其设为列表本身
class Boo {
has $.bar;
has @.baz is List;
}
我投票给了@BradGilbert 建议的 'is List' 版本...我尝试使用默认设置并收到这条令人敬畏的错误消息:
===SORRY!=== Error while compiling ...
Defaults on compound attribute types not yet implemented. Sorry.
Workaround: Create/Adapt TWEAK method in class Boo, e.g:
method TWEAK() {
@!baz := (initial values) unless @!baz;
}
为什么只读数组属性可以在 Raku 上修改 class,而另一方面,标量不能修改?
如何让@.baz
“只读”?
class Boo {
has $.bar;
has @.baz;
};
my $boo = Boo.new;
$boo.baz = (1, 2); # works ... ?
say $boo.baz;
$boo.bar = 1; #fails ... expected
我的落语版本:
This is Rakudo version 2020.05.1 built on MoarVM version 2020.05
implementing Raku 6.d.
baz
属性是只读的。
问题是 baz
属性是一个 Array
具有可变元素。
当您调用 $boo.baz
时,您基本上得到了对数组的引用。
一旦您获得了对数组的引用,您就可以执行您通常可以对该数组执行的任何操作。
say $boo.baz.VAR.name; # @!baz
当你赋值给一个数组时,你实际上是在告诉数组它将有新的内容。
my @a = ('a','b','c');
say @a.WHICH; # Array|94070988080608
@a = (1, 2, 3);
say @a.WHICH; # Array|94070988080608
请注意 .WHICH
没有改变。那是因为它仍然是同一个数组。它只是有新的内容。
当您分配给 public 数组属性时,会发生完全相同的事情。
您不是在分配新数组,而是在更改现有数组。
变量的所有行为都不是变量固有的,它们是由对象处理的。
在数组的情况下,处理分配的对象是 Array
.
最简单的修复方法是重载自动生成的访问器方法。
class Boo {
has $.bar;
has @.baz;
method baz () { @!baz.List }
}
如果您从不打算更改 @!baz 中的值,您可以将其设为列表本身
class Boo {
has $.bar;
has @.baz is List;
}
我投票给了@BradGilbert 建议的 'is List' 版本...我尝试使用默认设置并收到这条令人敬畏的错误消息:
===SORRY!=== Error while compiling ...
Defaults on compound attribute types not yet implemented. Sorry.
Workaround: Create/Adapt TWEAK method in class Boo, e.g:
method TWEAK() {
@!baz := (initial values) unless @!baz;
}