Class 由于 EVALFILE 而引入的符号

Class symbol introduction due to EVALFILE

Class 名称在 EVALFILE 之后的范围内可用,而文档可能另有说明。

EVALFILEstates的文档:

Slurps the specified file and evaluates it. Behaves the same way as EVAL with regard to Blob decoding, scoping, the $lang parameter and the $check parameter. Evaluates to the value produced by the final statement in the file when $check is not True.

EVALstates的文档:

since the set of symbols in a lexical scope is immutable after compile time, an EVAL can never introduce symbols into the surrounding scope.

我的输入文件是:

class SomeClass {
    method a () { "In SomeClass method a"; };
}

sub some-routine () {
    "Some routine";
}
> my $f = EVALFILE("/tmp/eval-bug.raku");
&some-routine

> $f()
Some routine

> some-routine()
===SORRY!=== Error while compiling:
Undeclared routine:
    some-routine used at line 1

以上三个执行符合文档,但以下不符合:

> SomeClass.a()
In SomeClass method a

那么 symbol 只是一个例程名称而不是 class 名称吗?或者这是一个错误?

在我看来,这是两件事的结合:1. 子例程 some-routine 未导出,以及 2. REPL 中的范围界定问题。

第一个可以通过两种方式修复:

our sub some-routine() {

sub some-routine() is export {

第二个是,在 REPL 的当前状态下,无法真正修复(我已经尝试过,但我的所有修复都在其他情况下引入了问题)。 REPL 当前实现为在您输入的每一行上执行 EVAL,同时尝试与下一行共享任何先前 EVAL 的元素。在运行时的当前状态下,不可能完全共享,这就是人们报告的有关 REPL 的许多问题的原因。

在 RakuAST 分支上的工作还意味着如果你愿意的话,让解释器的状态更加“客观化”,允许 EVALs 之间更好的状态共享,从而更好的 REPL。但这至少还需要几个月的时间才能登陆 Rakudo。

since the set of symbols in a lexical scope is immutable after compile time, an EVAL can never introduce symbols into the surrounding scope

这里的关键词是“词法作用域”。 类,但是,默认情况下不是词法作用域(不像例程),而是包作用域。这意味着它们默认引入了一个全局名称。如果您改写:

my class SomeClass {
    method a () { "In SomeClass method a"; };
}

然后这声明了一个词法范围的 class,不会引入全局名称,因此它不会安装在 EVALFILE.

之外的任何地方。

对我来说至少文档似乎是正确的;它明确提到了词法作用域,而“周围作用域”一词也带有文本(因此是词法)作用域的含义。但是,它可能会提到 EVALFILE 中声明的包范围内的东西将全局安装。