Estou escrevendo um pacote de desenho com algumas peças e tenho operadores e tipos de dados espalhados por toda parte. No entanto, eu não quero que os usuários adicionem os módulos correspondentes todas as vezes, pois seria muito complicado, por exemplo, eu teria uma Point
classe, uma Monoid
função e uma Style
classe em caminhos diferentes como este
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 {...}
Eu gostaria de ter um haskell
prelúdio semelhante lib/Package/Prelude.pm6
com o efeito de que eu posso escrever esses scripts
use Package::Prelude;
# I can use Point right away, Style etc...
em vez de fazer
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
Eu tentei muitas coisas:
- Esta versão não me dá o efeito certo, tenho que digitar todo o caminho a apontar, ou seja,
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 versão me fornece o
Point
imediato, mas tenho problemas com os operadores e assim por diante. Também gostaria de adicionar automaticamente tudo, desde as rotinas exportadas nos pacotes de exemplo 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
...
}
Vocês conhecem uma maneira melhor e rápida de obter um arquivo como um prelúdio?
unit class Package::Data::Point
. Você não precisa usarmodule
.Respostas:
O uso
EXPORT
está na direção certa. As principais coisas a saber são:Então a receita é:
use
todos os módulos dentro deEXPORT
EXPORT
Como exemplo, eu crio um módulo
Foo::Point
, incluindo um operador e uma classe:E, apenas para demonstrar que pode funcionar com vários módulos, também
Foo::Monad
:O objetivo é fazer com que isso funcione:
O que pode ser alcançado escrevendo um
Foo::Prelude
que contém:Há algumas esquisitices aqui para explicar:
sub
tem declarações implícitas de$_
,$/
e$!
. A exportação dessas informações resultaria em um erro de conflito de símbolo em tempo de compilação quando o módulo éuse
'd. Um bloco tem apenas um implícito$_
. Assim, facilitamos nossa vida com um bloco vazio aninhado.grep
é para garantir que não exportamos nosso$_
símbolo declarado implicitamente (graças ao bloco aninhado, é o único com o qual precisamos nos preocupar).::
é uma maneira de referenciar o escopo atual (etimologia:::
é o separador de pacotes).::.pairs
assim obtémPair
objetos para cada símbolo no escopo atual.Existe um mecanismo de reexportação especulado que pode aparecer em uma versão futura da linguagem Raku que eliminaria a necessidade desse pedaço de clichê.
fonte