Estoy escribiendo un paquete de dibujo con algunas partes, y tengo operadores y tipos de datos dispersos en todo. Sin embargo, no quiero que los usuarios agreguen los módulos correspondientes cada vez, ya que sería bastante complicado, por ejemplo, tendría una Point
clase, un Monoid
rol y una Style
clase en diferentes rutas como esta
unit module Package::Data::Monoid;
# $?FILE = lib/Package/Data/Monoid.pm6
role Monoid {...}
unit module Package::Data::Point;
# $?FILE = lib/Package/Data/Point.pm6
class Point {...}
unit module Package::Data::Style;
# $?FILE = lib/Package/Data/Style.pm6
class Style {...}
Me gustaría tener un haskell
preludio similar lib/Package/Prelude.pm6
con el efecto de que puedo escribir tales guiones
use Package::Prelude;
# I can use Point right away, Style etc...
en lugar de hacer
use Package::Data::Style;
use Package::Data::Point;
use Package::Data::Monoid;
# I can too use point right away, but for users not knowing the
# inner workings it's too overwhelming
He intentado muchas cosas:
- Esta versión no me da el efecto correcto, tengo que escribir toda la ruta al punto, es decir,
Package::Data::Point
...
unit module Package::Prelude;
# $?FILE = lib/Package/Prelude.pm6
use Package::Data::Style;
use Package::Data::Point;
use Package::Data::Monoid;
- Esta versión me da el
Point
derecho de inmediato, pero tengo problemas con los operadores y demás, también me gustaría agregar automáticamente todo, desde las rutinas exportadas en los paquetes de ejemplo mencionados.
# $?FILE = lib/Package/Prelude.pm6
use Package::Data::Style;
use Package::Data::Point;
use Package::Data::Monoid;
sub EXPORT {
hash <Point> => Point
, <Style> => Style
, <mappend> => &mappend
...
}
¿Conocen ustedes una forma mejor y más rápida de obtener un archivo similar a un preludio?
unit class Package::Data::Point
. No tienes que usarmodule
.Respuestas:
El uso
EXPORT
está en la dirección correcta. Las cosas clave a saber son:Entonces la receta es:
use
todos los módulos dentro deEXPORT
EXPORT
Como ejemplo, creo un módulo
Foo::Point
, que incluye un operador y una clase:Y, solo para demostrar que puede funcionar con múltiples módulos, también un
Foo::Monad
:El objetivo es hacer que esto funcione:
Lo cual se puede lograr escribiendo un
Foo::Prelude
que contenga:Hay algunas rarezas aquí para explicar:
sub
cuenta de las declaraciones implícitas$_
,$/
y$!
. Exportarlos daría lugar a un error de choque de símbolo en tiempo de compilación cuando el módulo esuse
'd. Un bloque solo tiene un implícito$_
. Por lo tanto, hacemos nuestra vida más fácil con un bloque desnudo anidado.grep
objetivo es asegurarnos de que no exportamos nuestro$_
símbolo declarado implícitamente (gracias al bloque anidado, es el único que nos debe preocupar).::
es una forma de hacer referencia al alcance actual (etimología:::
es el separador de paquetes).::.pairs
así obtienePair
objetos para cada símbolo en el alcance actual.Hay un mecanismo de reexportación especulado que puede aparecer en una futura versión del lenguaje Raku que eliminaría la necesidad de este poco de repetitivo.
fuente