为什么直接绑定"我们的&foo"不起作用,但通过动态查找进行间接绑定却有效?



为什么在模块 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吗?

  • 您的技术适用于所有符号吗?(我希望如此:),但会留给你来探索这些方面。

最新更新