有没有一种直接的方法来检查某个东西是否是 mixin?

问题描述

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');

当然没有人这样做:)

你最好只ask the Rakudo Metamodel

say $foo.^is_mixin; # OUTPUT: «1␤»

注意两点:

  1. is_mixin 元方法不返回 Bool
  2. name 元方法一样,它特定于 Raku 的 Rakudo 实现