What could be the reason that `require` doesn't work in some places?

元气小坏坏 提交于 2020-06-12 02:15:43

问题


Loading a module (ABC) with require works in one module of a distribution while it fails in another module of the distribution. What could be the reason that loading ABC with require fails in one place?

require Name::ABC;
my $new = Name::ABC.new(); # dies: You cannot create an instance of this type (ABC)

perl6 -v
This is Rakudo Star version 2019.03.1 built on MoarVM version 2019.03
implementing Perl 6.d.

The the required module: App::DBBrowser::Subqueries

App::DBBrowser::Union, line 80: OK *

App::DBBrowser::Join, lines 66 and 191: OK *

App::DBBrowser::Table::Extensions, line 49: OK *

App::DBBrowser, line 690: You cannot create an instance of this type (Subqueries) *

App::DBBrowser::CreateTable, line 112: You cannot create an instance of this type (Subqueries) *

* version 0.0.1


回答1:


$ cat XXX.pm6
unit class XXX;

$ cat ZZZ.pm6
module ZZZ {
    require XXX;
    XXX.new;
    say "OK";
}

$ perl6 -I. -e 'use ZZZ;'
===SORRY!===
You cannot create an instance of this type (XXX)

From the documentation:

require loads a compunit and imports definite symbols at runtime.

You are doing a runtime load of a module while also expecting the symbols for that module to exist at compile time. Instead you should use indirect name lookup (as shown at the bottom of the documentation page linked earlier):

$ cat XXX.pm6
unit class XXX;

$ cat ZZZ.pm6
module ZZZ {
    require XXX;
    ::("XXX").new;
    say "OK";
}

$ perl6 -I. -e 'use ZZZ;'
OK



回答2:


I think it's because require is a runtime load whereas use is compile time.

Generally I'd use use unless I have a need for dynamic module loading at runtime.




回答3:


use loads and imports a module at compile-time while require only loads a module at runtime.

Since the namespace is checked at compile-time, you can't just access it as you would a module that is loaded and imported with use.

You can get around that by symbolic references, but you can also capture the namespace into a variable.
(Assuming there is only a single namespace in the module, and it is the same as the name used to load it)

Foo.pm6:

unit module Foo;

sub fubar () { say 'fubar' }
my \Foo = do require Foo;
Foo::fubar(); # fubar␤

(Note that the name of the variable doesn't have to be the same.)



来源:https://stackoverflow.com/questions/56089611/what-could-be-the-reason-that-require-doesnt-work-in-some-places

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!