Module
的东西。我的问题与require的行为有关,该行为与所需名称空间的静态或动态解析一起使用。
在我看来,require不是正常的子例程。
[当我们将require与文字(模块名称)结合使用时,将在编译时对require进行评估并执行(?)。
示例:
my $response = ::('MODULE'); # this happens at runtime
say $response.^name; # printout: Failure # if MODULE doesn't exist (That means that the require was evaluated before the dynamic lookup, at complilation time)
try require MODULE; # this happens at compilation time (?)
当我们在动态查询中使用require时,动态查询的核心功能将在新的例程中进行代码转换/融合,该例程的行为与其部分和的总和不同。
就像我们将转换后的查询转换为增强的内容:
需要+动态查找=转换后的查找
示例:
try require ::($module); # this happens at runtime
“动态查找”的正常行为是搜索现有的“命名空间”(或符号)。如果未找到,则返回“失败”对象。
需要增强的“动态查找”进行常规查找,如果未加载$ module,则在raku modules目录中进行“搜索”,如果找到,则进行加载,否则抛出异常。
这是所提供功能的准确描述吗?
在我看来
require
不是正常的子例程。
这不是子例程。
如果在the official doc中搜索它,您会看到它在常规参考部分中列出了不是,而是语言参考的模块部分。这是一条语句,是编译器可以理解的语言的特殊部分。
try require MODULE; # this happens at compilation time (?)
几乎所有动作都发生在运行时。
Aafict在编译时发生的唯一一点是,编译器检查以查看MODULE
是否已被声明为符号。如果还没有,则编译器会声明它,并将其绑定到一个刚为此require
创建的空占位符包。
引用文档:
A
将安装占位符包...require
带有编译时符号Aiui它创建了一个占位符包,大概就是这样,如果在编译时分配或绑定了
require
的值,它会返回一些东西,但是如果它创建了一个占位符,则它仅绑定到编译时符号,并且仅当该符号不存在时才这样做。
try require ::($module); # this happens at runtime
正确。因此,与
try require FOO
情况不同,它在编译时从不创建任何符号。
的行为,而不只是”正常行为”的行为。因此,“动态查找”的正常行为是搜索现有的“命名空间”(或符号)。如果未找到,则返回“失败”对象。
始终是[[动态查找
::('jakar')
作为动态查找始终会查看当前程序是否动态地具有符号'jakar'
,并且是否没有返回Failure
。但是在require ::('jakar')
中,我不认为::('jakar')
是动态查找,或者如果是这样,那就不重要了。我认为这只是动态符号插值,是动态
构造符号
的一种方式。我不认为require
试图查看该符号是否已声明,并且如果确实发生查找,它认为它会忽略返回的值。它只需要一个符号将被解释为程序包名称,然后它将尝试加载该符号。加载成功后,它会创建一个匹配的符号-尽管如果本地词法作用域已经包含相同名称的符号,我还没找到去处;也许在这种情况下不创建一个符号?
require
增强的“动态查找”进行常规查找,如果未加载$module
,则在raku modules目录中进行“搜索”,如果找到,则进行加载,否则抛出异常。
您是否能够复制[[not要求装入程序包的情况?require
?
(我可以想象,如果模块加载器知道它已经被加载,就不会费心地加载它。但是require
本身是否参与了这一工作?肯定不会吗?)>
这是所提供功能的准确描述吗?
Afaik直到运行时都不会加载,无论require
的参数是在编译时声明的静态标识符还是动态构造的包名称。
从您对这个答案的评论中:
普通动态查找例程的不同行为,它不会再进一步检查存储库(仅检查名称空间)
这似乎将符号与程序包加载混合在一起。
jakar
和jakar不是同一个人! :)
require
会在编译期间做一些事情。
require Module;
say Module;
Module
的东西。因此它将在编译时安装一个具有该名称的临时符号。
这是它在编译时所做的唯一事情。(所以当我说“某事”时我就轻打了。)
if Bool.pick {
require module-which-does-not-exist;
module-which-does-not-exist.method-call()
}
[大约有一半的时间以上没有执行任何操作。另一半时间,它在运行时抱怨找不到模块。
((我选择了Bool.pick
而不是False
,因此编译时优化器肯定无法对其进行优化。)
当您使用标识符以外的名称进行调用时,它在编译时不知道模块将是什么。因此,它无法创建临时名称空间。
require 'Module';
say Module; # COMPILE ERROR: undeclared name
require Module; # RUNTIME ERROR: can't find 'Module'
say Module;
require 'Module'; # RUNTIME ERROR: can't find 'Module'
say ::('Module');
if False {
require Module;
say Module;
}
# no error at all
if False {
require 'Module';
say ::('Module');
}
# no error at all