Что может быть причиной того, что `require` не работает в некоторых местах? - PullRequest
7 голосов
/ 11 мая 2019

Загрузка модуля (ABC) с помощью require работает в одном модуле дистрибутива, а в другом модуле дистрибутива происходит сбой. В чем может быть причина того, что загрузка ABC с require не удалась в одном месте?

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.

Обязательный модуль: App :: DBBrowser :: Подзапросы

App :: DBBrowser :: Union , строка 80: OK *

App :: DBBrowser :: Join , строки 66 и 191: ОК *

App :: DBBrowser :: Table :: Extensions , строка 49: OK *

App :: DBBrowser , строка 690: Вы не можете создать экземпляр этого типа (подзапросы) *

App :: DBBrowser :: CreateTable , строка 112: вы не можете создать экземпляр этого типа (подзапросы) *

* версия 0.0.1

Ответы [ 3 ]

6 голосов
/ 12 мая 2019
$ 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)

Из документации :

требуется загрузка компонента и импорт определенных символов во время выполнения.

Вы выполняете время выполнениязагрузка модуля, ожидая, что символы для этого модуля будут существовать во время компиляции.Вместо этого вы должны использовать косвенный поиск имени (как показано внизу страницы документации, на которую ссылались ранее):

$ cat XXX.pm6
unit class XXX;

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

$ perl6 -I. -e 'use ZZZ;'
OK
5 голосов
/ 11 мая 2019

Я думаю, это потому, что require - это нагрузка времени выполнения, тогда как use - время компиляции.

Как правило, я бы использовал use, если у меня нет необходимости динамической загрузки модуля во время выполнения.

2 голосов
/ 13 мая 2019

use загружает и импортирует модуль во время компиляции, в то время как require загружает модуль только во время выполнения.

Поскольку пространство имен проверяется во время компиляции, вы не можете просто получить к нему доступ какВы могли бы модуль, который загружен и импортирован с use.

Вы можете обойти это с помощью символических ссылок, но вы также можете захватить пространство имен в переменную.
(Предполагая, что есть только одинпространство имен в модуле, и оно совпадает с именем, используемым для его загрузки)

Foo.pm6 :

unit module Foo;

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

(обратите внимание, чтоимя переменной не обязательно должно быть одинаковым.)

...