为什么直接绑定 `our &foo` 不起作用,但通过动态查找间接绑定呢?

jak*_*kar 5 module subroutine rakudo raku

为什么在模块 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) ...
Run Code Online (Sandbox Code Playgroud)

尝试在定义它的模块 TEST 之外运行子例程 r2 时出错。

rai*_*iph 5

TL;DR绑定到 anour是没有意义的。绑定到 anOUR::<&foo>是有效的。我喜欢给东西命名……你似乎发明了一种技术,我在此称之为“@jakar 的双重绑定our”。

为什么直接绑定只在模块内部有效

在对他对早先 SO 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) ...
Run Code Online (Sandbox Code Playgroud)

@jakar 的双重绑定 our

如果您希望能够声明一个符号并在模块内部和外部使用它并坚持使用绑定,那么您使用双重绑定声明它的技巧可能是可用的最佳技术:

    our &r1 := OUR::{'&r1'} := sub { ... }
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^ works *outside* module
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ works *inside* module
Run Code Online (Sandbox Code Playgroud)

我很好奇的一些事情:

  • 您是否能够确认任何重要的具体实际优势可以从绑定而不是分配中产生our

  • 人们是否想要解决“绑定到our变量毫无意义”的问题?如果是这样,他们会乐意使用@jakar 的双重绑定our吗?

  • 你的技术是否适用于所有的印记?(我希望如此,但会让你去探索这些方面。:))