为什么在模块 TEST 之外调用 r1 和 r2 时有区别?
module TEST {
our &r1 := OUR::{'&r1'} := sub {
say 'routine 1'
}
r1(); # routine 1
our &r2 := sub {
say 'routine 2'
}
r2(); # routine 2
}
import TEST;
say TEST::.keys; # (&r1 &r2)
TEST::r1(); # routine 1
TEST::r2(); # Cannot invoke this object (REPR: Uninstantiable; Callable) ...
尝试在定义子程序 TEST 的模块 TEST 之外运行子例程 r2 时出错。
TL;DR绑定到our
毫无意义。绑定到OUR::<&foo>
是有效的。我喜欢命名事物...看来你发明了一种技术,我特此称之为"@jakar的双重绑定our
"。
为什么直接绑定只在模块内部工作
在对他之前对 SO jnthn 的回答的评论中,jnthn 得出结论,我们可能会收到一条错误消息,或者可能是一条警告,大意是:
绑定到
our
变量是毫无意义的使用our
。
(他的意思是,正如您所发现的那样,绑定仅在模块内部工作,而不能在模块外部工作。
有一个旧的且仍然悬而未决的问题,在 BEGIN 时绑定变量不会在深入讨论一般问题的运行时停留。
为什么动态查找在模块外部工作
从 以核心命名空间开头的符号总是被导出,jnthn 指出:
藏匿处始终开放,可以戳入符号。
因此,忽略模块中符号的使用,您的代码正在执行以下操作:
module TEST {
OUR::{'&r1'} := sub { say 'routine 1' }
our &r2;
}
import TEST;
TEST::r1(); # routine 1
TEST::r2(); # Cannot invoke this object (REPR: Uninstantiable; Callable) ...
@jakar的双重绑定our
如果希望能够声明一个符号并在模块内外使用它,并坚持使用绑定,那么使用双重绑定声明它的技巧可能是可用的最佳技术:
our &r1 := OUR::{'&r1'} := sub { ... }
^^^^^^^^^^^^^^^^^^^^^^^^^^^ works *outside* module
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ works *inside* module
我好奇的一些事情:
您是否能够确认绑定而不是分配
our
可以获得的任何重大的特定和实际优势?人们是否想绕过"绑定到
our
变量毫无意义"的问题?如果是这样,他们会乐意使用@jakar的双重绑定our
吗?您的技术适用于所有符号吗?(我希望如此:),但会留给你来探索这些方面。