有没有一种方法可以安全地重新声明符号?


9

我经常发现自己在REPL中进行实验,并且会说类似以下内容:

subset Bar of Int where * %% 57;

然后,我Bar尝试检查-ness的情况。

一切都很高兴,直到我意识到我想更改的定义Bar

如果我只是重新定义Bar,我会得到一个Redeclaration of symbol例外。

我尝试使用MONKEY-TYPINGaugment像这样:

use MONKEY-TYPING;
augment subset Bar of Int where * %% 37;

但这使我犯了同样的错误。

我为什么要这个?因此,我可以迭代我的子集(或类或其他符号)的定义,同时重用我已经在历史记录中键入的测试。

Answers:


3

我认为REPL通过- EVAL在新的嵌套词法作用域中对每个新输入赋值来实现其魔力的一部分。因此,如果使用声明事物,my则可以使用稍后输入的声明来遮盖它们:

my subset Bar of Int where * %% 57;
sub take-Bar(Bar $n) { say "$n is Bar" }
take-Bar 57;

my subset Bar of Int where * %% 42;
sub take-Bar(Bar $n) { say "$n is Bar" }
take-Bar 42;

如果您省略my,则将使用for subsetclass声明,our因为our实际上是my+将符号添加到封装中...; 原来,如果您从包装中删除了该符号,则可以在以后再次对其进行阴影处理:

subset Bar of Int where * %% 57;
GLOBAL::<Bar>:delete;
subset Bar of Int where * %% 42;
42 ~~ Bar;

注意:这些结果仅来自我在REPL中的实验。我不确定是否还有其他未知的副作用。


8

REPL有它的缺点。它是EVAL试图协同工作的语句的精心构建。有时那行不通。

我想我们能做的最好的就是引入REPL命令,该命令会使它忘记以前所做的一切。欢迎补丁!:-)


因此,如果我理解正确的话,我在和上的路就走对了use MONKEY-TYPINGaugment但是它们在REPL中还不能正常工作(还可以吗?),因为它需要很多魔术和鸭子胶带。
daotoad

1
AFAIK,您只能使用扩充内容添加到类中。您要尝试替换一个子集
伊丽莎白·马蒂森

1
@daotoad要替换,您可以使用supersede,但我相信目前仍然没有实现。
user0721090601 '19

1
Supersede仍未实现,但无论如何只能在已安装的模块级别上运行。supersede函数应允许一个模块指示应加载该模块,而不是另一个模块/版本。因此,当被询问是否可以提供给定的模块时,这是对CompUnitRepo的提示。
伊丽莎白·马蒂森
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.