我有一个模块AttrX::Mooish,它实现了Moo/Moose框架的一些属性特性(lazynes,trigger等).我还希望模块对最终用户尽可能透明,这意味着支持私有和公共属性.它的工作原理是将属性的容器替换为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方法获取参数化类型的基本类型的好主意.
到目前为止,最大的问题是:
of方法并测试其输出.不幸的是,如果一个类提供了FALLBACK非常不清楚的错误消息(关于AUTOGEN的那个)就会产生.:no_fallback是可取的,但确定和子集类型有自己的find_method不支持命名参数,我最终得到另一个错误消息.$!coerce-type)compose应用于Attribute对象(实际上是声明了属性),我会在运行时稍后将其找到.猜测它与构成时间有关的东西.但是想确定这里是否遗漏了什么.$value ~~ $type?[评论表明这个过时的问题本应在 2020 年结束,但它从未结束。这是一个非常简短的答案,以防有人遇到这个问题。]
在提出这个问题后的某个时间,提问者对 Raku 的强制机制进行了重大修改。请参阅关于新强制的报告。这种新的强制转换语法位于文档中。
使用这种新样式,问题中的以下行:
my Array[Str] $a = ["a", "b", "c"];
say $a;
# OUTPUT: Type check failed in assignment to $a;
# expected Array[Str] but got Array ($["a", "b", "c"])
Run Code Online (Sandbox Code Playgroud)
变成
my Array[Str]() $a = ["a", "b", "c"];
say $a;
# OUTPUT: [a b c]
Run Code Online (Sandbox Code Playgroud)
(也就是说,Array[Str]()意味着“可以强制转换为字符串数组的东西”。这不同于Array[Str()](“可以强制转换为字符串的东西的数组”) 和Array[Str()]()(“可以强制转换为字符串的东西的数组”可以强制转换为字符串”)。)
同样,问题的以下部分现在有了答案:
赋值运算符是否使用单个入口点来执行所有强制/类型检查?理想情况下,我会简单地[定义如何将类型强制为我的类型]
使用新的强制协议,“单一入口点”是方法COERCE,用户可以为其类型定义该方法,以教 Raku 如何强制转换为这些类型。
| 归档时间: |
|
| 查看次数: |
193 次 |
| 最近记录: |