有没有一种直接的方法来检查某些东西是否是混入?

Is there a straightforward way to check if something is a 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] 我没有搜索 roast 但可以想象在类型名称中使用 + 是只是一个约定,不是语言规范的一部分。

[3] 根据我在下面的第一条评论,我发现你的问题是 XY problem 的一个例子它; and/or 术语混乱,每秒。这个答案的其余部分解释了我的意思。

Is there a straightforward way to check if a container is a 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 元方法不 return Bool
  2. name 元方法一样,它特定于 Raku 的 Rakudo 实现