Экспорт динамически изменяемых переменных?

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

У меня есть роль грамматики с прототипом токена (пример упрощен, чтобы продемонстрировать идею):

proto token foo {*}
token foo:sym<a> {
   :my $*delimiter = q<">;
   \" ~ \" <value>
}
token foo:sym<b> {
   :my $*delimiter = q<'>;
   \' ~ \' <value>
}
token value {
    .+? <?before $($*delimeter) || $($*custom-delimiter)>
}

Когда роль поглощена грамматикой, я хочу $*custom-delimiter быть установленным грамматикой. Конечно, я могу объявить это везде, где <foo> нужно. Но иногда можно предварительно инициализировать его универсальным значением по умолчанию. Что-то вроде:

{ $*custom-delimiter //= $default-delimiter }

в value маркер будет работать. Но внешняя предварительная декларация все еще была бы необходима.

Я надеялся, что:

our $*custom-delimiter is export = $default-delimiter;

в объеме модуля, где объявлена ​​роль будет работать. Но, видимо, это не так. Итак, вопрос: есть ли элегантные решения для этого?

На самом деле, я также надеюсь, что решение позволит перенести декларацию $*delimiter в foo вне определения токена тоже.

В качестве примечания: моя первая мысль была о добавлении параметра в токен. Но иметь абсолютно одинаковые подписи для каждого варианта тоже выглядит ужасно:

token foo:sym<a> ( $*custom-delimiter = $default-delimiter ) {
}
token foo:sym<b> ( $*custom-delimiter = $default-delimiter ) {
}
token foo:sym<c> ( $*custom-delimiter = $default-delimiter ) {
}

Другой подход - иметь что-то вроде:

token pre-foo ( $*custom-delimiter = $default-delimiter ) {
    <foo>
}

В этом случае потребуется дополнительный метод в классе действий для распространения $/<foo>.ast на один уровень выше.

0 ответов

Основываясь на некоторой тестовой работе, которую я проделал в одном из моих модулей, чтобы разрешить настройки с заданной областью для модуля, вы можете это сделать, но вам нужно будет использовать подгруппу EXPORT.

Я предполагаю, что причина в том, что при выполнении EXPORT мы можем установить то, что является явно новой динамической переменной, а не новым символом, связанным с существующей динамической переменной - последнее из которых для меня очень неясно.

Мне кажется, это работает нормально.

# filename: Foo.rakumod
# no 'unit module', etc

sub EXPORT {
  proto token foo {*}
  token foo:a { … }
  token foo:b { … }

  Map.new: 
    '&foo'      => &foo,
    '$*dynamic' => my $ = 'default'
}

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