【问题标题】:Why does direct binding of an `our &foo` not work, but indirecting via a dynamic lookup does?为什么直接绑定 `our &foo` 不起作用,但通过动态查找间接绑定呢?
【发布时间】:2020-06-06 18:43:01
【问题描述】:

为什么在模块 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 之外运行子例程 r2 时出错。

【问题讨论】:

    标签: module raku subroutine rakudo


    【解决方案1】:

    TL;DR 绑定到our 是没有意义的。绑定到OUR::<&foo> 是有效的。我喜欢给事物命名……看来你发明了一种技术,我特此称之为“@jakar 的双重绑定our”。

    为什么直接绑定只在模块内部起作用

    在对他对an earlier SOjnthn 的回答的评论中,jnthn 得出的结论是,我们可能会收到一条错误消息或警告,大意是:

    绑定到our 变量是毫无意义地使用our

    (他的意思是绑定只在模块内部起作用,而不是在外部,正如您所发现的那样。)

    有一个老问题Binding a variable at BEGIN time doesn't stick around for runtime 深入讨论了一般问题。

    为什么动态查找在模块外起作用

    来自Symbols that start with core namespaces always get exported,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吗?

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-14
      • 1970-01-01
      相关资源
      最近更新 更多