Class 由于 EVALFILE 而引入的符号
Class symbol introduction due to EVALFILE
Class 名称在 EVALFILE
之后的范围内可用,而文档可能另有说明。
EVALFILE
states的文档:
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.
EVAL
states的文档:
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 分支上的工作还意味着如果你愿意的话,让解释器的状态更加“客观化”,允许 EVAL
s 之间更好的状态共享,从而更好的 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
中声明的包范围内的东西将全局安装。
Class 名称在 EVALFILE
之后的范围内可用,而文档可能另有说明。
EVALFILE
states的文档:
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.
EVAL
states的文档:
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 分支上的工作还意味着如果你愿意的话,让解释器的状态更加“客观化”,允许 EVAL
s 之间更好的状态共享,从而更好的 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
中声明的包范围内的东西将全局安装。