【发布时间】:2018-11-15 19:22:45
【问题描述】:
基本上,这个问题更多的是关于语法,但我认为这可能是关于动态变量的更有趣的练习。
我有一个带有原型标记的语法角色(示例被简化以展示这个想法):
proto token foo {*}
token foo:sym<a> {
:my $*delimiter = q<">;
\" ~ \" <value>
}
token foo:sym<b> {
:my $*delimiter = q<'>;
\' ~ \' <value>
}
token value {
.+? <?before $($*delimeter) || $($*custom-delimiter)>
}
当角色被语法消耗时,我希望 $*custom-delimiter 由语法设置。当然,我可以在需要<foo> 的任何地方声明它。但有时可以使用通用默认值对其进行预初始化。比如:
{ $*custom-delimiter //= $default-delimiter }
在value 令牌中会起作用。但仍需要外部预先声明。
我希望:
our $*custom-delimiter is export = $default-delimiter;
在声明角色的模块范围内可以工作。但显然它没有。所以,问题是:有什么优雅的解决方案吗?
实际上,我也希望该解决方案也允许将$*delimiter 中的foo 声明移到令牌定义之外。
附带说明:我的第一个想法是为令牌添加参数。但是对于每个变体都具有完全相同的签名看起来也很糟糕:
token foo:sym<a> ( $*custom-delimiter = $default-delimiter ) {
}
token foo:sym<b> ( $*custom-delimiter = $default-delimiter ) {
}
token foo:sym<c> ( $*custom-delimiter = $default-delimiter ) {
}
另一种方法是:
token pre-foo ( $*custom-delimiter = $default-delimiter ) {
<foo>
}
在这种情况下,操作类中需要一个额外的方法来传播$/<foo>.ast 上一级。
【问题讨论】:
-
今晚我太累了,无法理解你的问题。但是你知道角色可以被参数化,对吧?例如
role foo[$bar = 99] { method baz { say $bar } }; foo[42].baz; # 42。这相关吗? -
从来不需要它,所以 - 这是一个很好的提醒!但是——不,不幸的是。标记
foo在使用不同分隔符的不同上下文中由相同的语法使用。 -
您不能使用
is export导出,但您可以使用 EXPORT 子,没有任何问题 IME。我一直在成功地使用它,以允许模块的每个use语句为某些设置插入自己的范围,否则这些设置必须是全局的
标签: raku