如果需要该文件,Perl 6 应该运行 MAIN 吗? [英] Should Perl 6 run MAIN if the file is required?

查看:37
本文介绍了如果需要该文件,Perl 6 应该运行 MAIN 吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个简短的 Perl 6 程序,它声明了一个 MAIN 子例程.如果我直接执行程序,我应该只看到输出:

Here's a short Perl 6 program that declare a MAIN subroutine. I should only see output if I execute the program directly:

$ cat main.pm6
sub MAIN { say "Called as a program!" }

而且我直接执行程序时看到了输出:

And I see output when I execute the program directly:

$ perl6 main.pm6
Called as a program!

如果我将其作为模块加载,则看不到输出:

If I load it as a module, I see no output:

$ perl6 -I. -Mmain -e "say 'Hey'"
Hey

同样,如果我在程序内部使用它,我看不到输出:

Same if I use it from inside the program, I see no output:

$ perl6 -I. -e 'use main'

但是,如果我使用 require,我会得到输出:

But, if I use require, I get output:

$ perl6 -I. -e 'require <main.pm6>'
Called as a program!

概要 06 字面意思是编译单元被直接调用而不是被要求.是否还有其他原因因为 require 在运行时起作用(尽管 S06 不排除这一点)?

Synopsis 06 literally says the compilation unit was directly invoked rather than by being required. Is there something else going on because require works at runtime (although S06 doesn't exclude that)?

我在 Rakudo Star 2016.07 和 2016.10 上得到了相同的行为.

I get the same behaviour with Rakudo Star 2016.07 and 2016.10.

推荐答案

首先,让我们看看 require 应该如何表现:

First, let's take a look at how require is supposed to behave:

根据(非权威)设计文档

或者,可以直接提及文件名,这会安装一个对当前词法范围有效匿名的包,并且只能由模块安装的任何全局名称访问:

Alternately, a filename may be mentioned directly, which installs a package that is effectively anonymous to the current lexical scope, and may only be accessed by whatever global names the module installs:

只有明确提到的名字才能被导入.为了保护词条在运行时的神圣性,require 不能对其进行修改.

Only explicitly mentioned names may be so imported. In order to protect the run-time sanctity of the lexical pad, it may not be modified by require.

结合 S06

当且仅当执行此调用:

a) 编译单元被直接调用,而不是被另一个编译单元要求 [...]

a) the compilation unit was directly invoked rather than by being required by another compilation unit [...]

我的理解是,不应运行未明确导入主线词法范围的子 MAIN.

it is my understanding that a sub MAIN not explicitly imported into the mainline lexical scope should not be run.

遗憾的是,用户文档对通过文件导入运行时的情况保持沉默名称,并快速浏览(权威)测试套件(特别是S11-modules/require.t) 也没有给出答案我可能只是错过了.

Sadly, the user documentation is quiet on the case of runtime importation via file name, and a quick glance at the (authorative) test suite (in particular S11-modules/require.t) did not yield an answer either, though I just might have missed it.

现在,让我们来看看乐堂的行为:

Now, let's take a look at how Rakudo behaves:

正如预期的那样,通过静态或动态模块名称导入运行时

As expected, runtime importation via static or dynamic module name

require main;

require ::('main');

不会运行 MAIN 除非它被声明为 is export 并且显式导入,即

will not run MAIN unless it is both declared is export and explicitly imported, ie

require main <&MAIN>;

require ::('main') <&MAIN>;

分别.

通过文件名导入

require 'main.pm6';

将立即运行MAIN.

事实上,如果你通过

require 'main.pm6' <&MAIN>;

sub 将执行两次:一次是在加载编译单元时,第二次是在运行时执行其工作时在主线范围内查找和运行任何 MAIN 子.

the sub will be executed twice: Once when loading the compilation unit, and a second time when the runtime does its job looking and running any MAIN sub in the mainline scope.

Rakudo 显然将带有文件名参数的 require 或多或少类似于 EVALFILE 并执行其主线,包括它遇到的任何子 MAIN.

Rakudo apparently treats a require with file name argument more or less like EVALFILE and executes its mainline, including any sub MAIN it encounters.

不是我所期望的,可能只是一个错误.

That's not what I would have expected and possibly just a bug.

这篇关于如果需要该文件,Perl 6 应该运行 MAIN 吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆