问题描述
Raku mixins 有两个(或多个)性质,在同一个容器中组合多个值,或者值与角色一起。但是,据我所知,没有一种直接的方法可以检查不是由您创建的变量中的“混合性”。
这可能是个伎俩
my $foo = 3 but Stringy;
say $foo.^name ~~ /\+/;# OUTPUT: «「+」»
但是我还缺少其他可以直接查找的属性吗?
解决方法
我认为您缺少 ^roles
和 ^parents
元方法:
my $foo = 3 but Stringy;
dd $foo.^roles; # (Stringy,Real,Numeric)
dd $foo.^parents; # (Int,)
,
TL;DR我不可靠的解决方案[1]比不可靠的解决方案更简单、更快[2] 应该适用于问题 Y 和问题 X[3]:
sub is-mixin ($object) { $object.^is_mixin =:= 1 }
say is-mixin 3; # False
say is-mixin 3 but 'bar'; # True
脚注
[1]“警告:[role Metamodel::Mixins
] 是 Rakudo 实现的一部分,而不是语言规范的一部分。”>
[2] 我没有搜索过烤,但可以想象在类型名称中使用 +
只是一种约定,而不是语言规范。
[3] 根据我在下面的第一条评论,我发现您的问题是 XY problem 的一个示例;和/或术语混淆,每秒。这个答案的其余部分解释了我的意思。
有没有一种直接的方法来检查一个容器是否是一个 mixin?
“容器”一词在 Raku 中具有技术含义。它指的是遵循 Raku 的容器协议的值。当值后跟 =
以调用“赋值”时应用容器协议。
您所询问的似乎与这样的 容器 无关,因为它不同于 值。并且有充分的理由认为这对你来说无关紧要——你只是感兴趣的是测试一个值是否是一个混入,而“容器”方面是一个红鲱鱼,要么是因为你没有意思是 Raku 中通常意义上的“容器”,或者因为容器无论如何都无关紧要,因为容器是一个值,所以任何用于测试值的方法都可以用于测试容器。
例如,看看你的“把戏”:
my $foo = 3 but Stringy;
say $foo.^name ~~ /\+/;# OUTPUT: «「+」»
这个技巧与使用 Raku 中“容器”一词的正常技术用法的任何容器方面都无关。如果您编写以下不涉及容器的内容,您会得到相同的结果:say (3 but Stringy).^name ~~ /\+/;# OUTPUT: «「+」»
.
因此,在我的解决方案中,我假设您的意思只是一个值,知道您最终的重点是否放在容器上实际上并不重要。
如果我的假设是错误的,并且这会产生影响,我敦促您解释您正在尝试做的事情的 X,而不仅仅是 Y。
,你的技巧让你的代码变得脆弱,因为它不期望
$foo.^set_name('The Spanish Inquisition');
当然没有人这样做:)
say $foo.^is_mixin; # OUTPUT: «1»
注意两点:
-
is_mixin
元方法不返回Bool
- 与
name
元方法一样,它特定于 Raku 的 Rakudo 实现