Как я могу динамически экспортировать классы в raku?

Я обновляю модуль раку (Physics::Measure)

Мой старый код выглядит так:

unit module Physics::Measure ...

class Length             is Measure is export {}
class Mass               is Measure is export {}
class Current            is Measure is export {}
...

На стороне клиента делаем:

use Physics::Measure;

say my Length $b = 15m;    #15m

Чтобы справиться с локализацией, я хотел бы объявить и экспортировать эти классы программно, например:

my @names = <Length Mass Current>;

for @names -> $name {
    class ::($name) is Measure is export {}
}

Это дает ошибку Name ::($name) is not compile-time known, and can not serve as a package name.

Хорошо, возможно (из документации) я могу сделать что-то вроде:

my package EXPORT::DEFAULT {
    for @names -> $name {
        OUR::($name) := $name;
    }
}

-или, может быть, с циклом for, будет определено позднее-

sub EXPORT {
    Map.new:
        ($name => Length is Measure)
}

Пожалуйста, может ли кто-нибудь подсказать, как лучше всего (i) динамически объявлять классы и (ii) затем экспортировать их???

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
6
0
93
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Секрет на самом деле в том, что имена классов не должны быть динамическими, а имена, с которыми они экспортируются, должны быть динамическими:

# file lib/Physics/Measure.rakumod
class Length  {}
class Mass    {}
class Current {}

sub EXPORT(*@names) {
    Map.new( @names.map: -> $from, $to { $to => ::($from) } )
}

Это позволит вам указать исходное имя -> нужные пары имен как таковые:

$ raku -Ilib -e 'use Physics::Measure <Length Foo Current Bar>; dd Foo, Bar'
Length
Current

Это базовый механизм обработки любых неименованных аргументов в операторе use. Использование именованных аргументов в настоящее время обрабатывается обработчиком по умолчанию, но, к сожалению, в настоящее время это невозможно. Гораздо более естественным интерфейсом был бы :Length<Foo>, :Current<Bar>.

Спасибо за ваш быстрый ответ --- это еще половина дела, пока все хорошо, но я хочу иметь возможность выбирать разные имена классов, например <Longueur Masse Temps>, из файла локализации... так могу ли я объявлять имена классов также динамически?

librasteve 03.04.2024 18:23

Но это только моя точка зрения: нельзя не попасть в страну QAST/RakuAST. Но вы можете переименовать их при импорте в область.

Elizabeth Mattijsen 03.04.2024 19:15

Ах хорошо. Что ж, в этом модуле существует острая потребность в макросах (код мог бы быть намного проще/быстрее, если бы можно было создать экземпляры 227-ми объектов-модулей и хранить их в предварительной компоновке)... но я оставляю это для следующего большого обновления в надеюсь, что макросы появятся ;-) ... тем временем, я думаю, что я закреплю имена классов в каждом локальном варианте модуля Measure (т.е. использую менеджер пакетов, чтобы общий код предоставлялся "родительским" модулем, а затем каждым дочерняя версия — это локализованная версия... ценим рекомендации!

librasteve 03.04.2024 20:13

Я не думаю, что макросы также решат вашу проблему, поскольку они также запускаются во время компиляции. Не могли бы вы привести пример того, что вы планируете сделать? Чтобы мы могли увидеть, понимаем ли мы друг друга?

Elizabeth Mattijsen 03.04.2024 21:20

извините, макросы были в стороне --- я не продумал это настолько, чтобы задать убедительный вопрос

librasteve 04.04.2024 12:46

Другие вопросы по теме