【问题标题】:Can I introspect a variable to directly discover what subset it was declared with?我可以自省一个变量以直接发现它是用什么子集声明的吗?
【发布时间】:2017-04-05 12:51:34
【问题描述】:

有没有一种方法可以内省变量以直接找出它声明的子集?这里我创建了一个子集,但自省将我指向它的基本类型:

> subset Prime of Int where .is-prime
(Prime)
> my Prime $x = 23
23
> $x.WHICH
Int|23

我知道它必须将信息存储在某个地方,因为如果我尝试重新分配与子集不匹配的值,它会失败:

> $x = 24
Type check failed in assignment to $x; expected Prime but got Int (24)
in block <unit> at <unknown file> line 1

我尝试搜索代码,但我很快就进入了像container.cperl6_ops.c 这样的文件,C 代码让我眼前一亮。我认为X::TypeCheck::Assignment 可能会有所帮助(请参阅core/Exception.pm),但我不清楚expected 值的来源。 (另见this commit

我觉得我错过了一些明显的东西。

我可以检查某些内容是否与子集匹配,但这并不能告诉我它是否是使用特定子集声明的:

> my Int $y = 43;
43
> $y ~~ Prime;
True

我正在使用 Rakudo Star 2017.01


受到 Zoffix 在a recent post 中使用子集的启发。

【问题讨论】:

  • containershould-be 类型不同于值的 actually-is 类型存放在那个容器中。一个类比是物理容器上的标签,说明容器中应该有什么类型的东西,而不是实际在容器中的东西上的标签。所以my Prime $x = 23 创建了一个符号$x,它绑定到一个标量容器,should-be 类型Prime 实际上包含一个Int。应用于容器的大多数操作都作用于容​​器中的值,而不是容器本身。您需要使用.VAR,如 lizmat 的回答中所见,以获取 var 的类型。

标签: introspection raku


【解决方案1】:

您存储在$x 中的值是Int。容器(您键入 Prime)可以接受它,因为 PrimeInt 的子类型。

所以你感兴趣的不是容器中的值,而是容器的type。为了获得容器,Perl 6 有.VAR 方法。这有一个.of method 来获取类型:

$ 6 'subset Prime of Int where .is-prime; my Prime $x; dd $x.VAR.of'
Prime

【讨论】:

  • 谢谢!我想我明白了。容器$x 被键入为Prime,这允许它保存任何满足Prime 约束的Int$x.WHAT 告诉我它的内容,而$x.VAR.of 告诉我容器的类型,
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-15
  • 2022-01-09
  • 2020-07-27
  • 1970-01-01
相关资源
最近更新 更多