Cargar un módulo (ABC) con require funciona en un módulo de una distribución mientras falla en otro módulo de la distribución. ¿Cuál podría ser la razón por la que la carga ABC con require falla en un lugar?

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.

El módulo requerido: Aplicación :: DBBrowser :: Subconsultas

Aplicación :: DBBrowser :: Union, línea 80: OK *

Aplicación :: DBBrowser :: Join, líneas 66 y 191: OK *

Aplicación :: DBBrowser :: Tabla :: Extensiones, línea 49: OK *

Aplicación :: DBBrowser, línea 690: no puede crear una instancia de este tipo (subconsultas) *

Aplicación :: DBBrowser :: CreateTable, línea 112: no puede crear una instancia de este tipo (subconsultas) *

* versión 0.0.1

7
sid_com 11 may. 2019 a las 13:52

3 respuestas

La mejor respuesta
$ 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)

De la documentación:

require carga una compunidad e importa símbolos definidos en tiempo de ejecución.

Está realizando una carga de tiempo de ejecución de un módulo mientras espera que los símbolos para ese módulo existan en tiempo de compilación. En su lugar, debe usar la búsqueda indirecta de nombres (como se muestra en la parte inferior de la página de documentación vinculada anteriormente):

$ cat XXX.pm6
unit class XXX;

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

$ perl6 -I. -e 'use ZZZ;'
OK
6
ugexe 12 may. 2019 a las 14:58

Creo que es porque require es una carga de tiempo de ejecución mientras que use es tiempo de compilación.

En general, usaría use a menos que necesite cargar módulos dinámicos en tiempo de ejecución.

5
Scimon Proctor 25 nov. 2019 a las 20:37

use carga e importa un módulo en tiempo de compilación mientras que require solo carga un módulo en tiempo de ejecución.

Dado que el espacio de nombres se verifica en tiempo de compilación, no puede acceder a él como lo haría con un módulo que se carga e importa con use.

Puede evitar eso mediante referencias simbólicas, pero también puede capturar el espacio de nombres en una variable.
(Suponiendo que solo hay un único espacio de nombres en el módulo, y es el mismo que el nombre utilizado para cargarlo)

Foo.pm6 :

unit module Foo;

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

(Tenga en cuenta que el nombre de la variable no tiene que ser el mismo).

3
Brad Gilbert 13 may. 2019 a las 14:29