10

我有一个模块AttrX::Mooish,它实现了 Moo/Moose 框架的一些属性特性(懒惰、触发器等)。我还希望模块对最终用户尽可能透明,这意味着支持私有和公共属性。它通过用 a 替换属性的容器Proxy并将其值存储在外部存储中来工作。这也意味着 Perl6 所做的所有类型检查和强制转换现在都是我的责任。我的目标是尽可能地模仿默认行为。即对于最终用户:

has MyClass @foo is mooish(...);

必须与没有应用特征的情况相同。不幸的是,类型操作的主题在语言核心中是如此复杂和不统一,以至于我解决的问题越多,我之后遇到的问题就越多。例如:

my Str @a = <a b c>; my Str @b = [1,2,3]

Type check failed in assignment to @b; expected Str but got Int (1)

正如预期的那样。

my Str @a; say @a.WHAT

(Array[Str])

当然。

my Array[Str] $a = ["a", "b", "c"];

Type check failed in assignment to $a; expected Array[Str] but got Array ($["a", "b", "c"])

出色地....

my Array[Str] $a = <a b c>;

Type check failed in assignment to $a; expected Array[Str] but got List ($("a", "b", "c"))

甚至不List强求Array

难怪我的特征代码中的最后一个类型检查行:

$coerced-value ~~ $attr.type

尽管变量/属性分配中使用的值/类型相同,但在这里和那里都失败了。

我有一个不希望得到任何肯定答案的问题:赋值运算符是否使用了一个入口点来执行所有强制/类型检查?理想情况下,我会简单地:

$value = coerce($value, $type);
check-type($value, :type($attr.type), :name($attr.name))

我试图从语法上追溯,但还没有足够的空闲时间来完成这项工作。另外,我不知道也不能真正理解的主要是nqp。

但由于不太可能存在这样的入口点,我想询问与该领域相关的任何建议。例如,#perl6 上的 SmokeMachine 为我提供了使用.^parents方法获取参数化类型的基本类型的好主意。

到目前为止,最大的问题在于:

  1. 要检查类型是否已参数化,我不能使用单个角色或类来匹配。到目前为止,我唯一的方法是查找是否有of方法并测试其输出。不幸的是,如果一个类提供了FALLBACK非常不清楚的错误消息(关于 AUTOGEN 的错误消息),则会产生。:no_fallback是可取的,但确定和子集类型有自己的find_method不支持命名参数,我最终得到另一个错误消息。
  2. 如果在我的 trait 角色的方法中准备类型相关的属性 ( $!coerce-type)compose应用于Attribute对象(实际上是在其中声明了属性),我稍后会在运行时统一化它们。猜测它与撰写时间有关。但是想确定这里是否遗漏了什么。
  3. 有没有比执行类型检查更好的方法$value ~~ $type
4

0 回答 0