Я пишу чертежный пакет с некоторыми частями, и у меня есть операторы и типы данных, разбросанные по всему. Однако я не хочу, чтобы пользователи добавляли соответствующие модули каждый раз, так как это было бы довольно грязно, например, у меня был бы Point
класс, Monoid
роль и Style
класс по разным путям, как этот
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 {...}
Я хотел бы иметь haskell
подобное lib/Package/Prelude.pm6
вступление с эффектом, что я могу писать такие сценарии
use Package::Prelude;
# I can use Point right away, Style etc...
вместо того, чтобы делать
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
Я перепробовал много вещей:
- Эта версия не дает мне нужного эффекта, я должен набрать весь путь до точки, то есть
Package::Data::Point
...
unit module Package::Prelude;
# $?FILE = lib/Package/Prelude.pm6
use Package::Data::Style;
use Package::Data::Point;
use Package::Data::Monoid;
- Эта версия дает мне
Point
право сразу, но у меня возникают проблемы с операторами и так далее, также я хотел бы просто автоматически добавить все из экспортированных подпрограмм в упомянутые примеры пакетов.
# $?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
...
}
Знаете ли вы, люди, лучший и быстрый способ получить такой прелюдоподобный файл?
unit class Package::Data::Point
. Вам не нужно использоватьmodule
.Ответы:
Использование
EXPORT
в правильном направлении. Ключевые вещи, которые нужно знать:Итак, рецепт таков:
use
все модули внутриEXPORT
EXPORT
В качестве примера я создаю модуль
Foo::Point
, включающий оператор и класс:И, просто чтобы продемонстрировать, что он может работать с несколькими модулями, также
Foo::Monad
:Цель состоит в том, чтобы сделать эту работу:
Что может быть достигнуто путем написания,
Foo::Prelude
который содержит:Здесь есть несколько странностей, чтобы объяснить:
sub
Имеет неявные декларации$_
,$/
и$!
. Их экспорт может привести к ошибке конфликта символов во время компиляции, когда модуль имеет значениеuse
«d». Блок имеет только неявный$_
. Таким образом, мы делаем нашу жизнь проще с вложенным голым блоком.grep
сделано для того, чтобы мы не экспортировали наш неявно объявленный$_
символ (благодаря вложенному блоку, он единственный, о котором нам нужно заботиться).::
способ ссылки на текущую область (этимология:::
разделитель пакетов)::.pairs
таким образом получаетPair
объекты для каждого символа в текущей области видимости.Существует предполагаемый механизм реэкспорта, который может появиться в будущем выпуске языка Raku, который устранит необходимость в этом кусочке.
источник