Как переопределить функцию NQPMatch.Str
... Или как изменить $<sigil>.Str
значение от token sigil { ... }
независимо от совпадающего текста. Да я спрашиваю, как обмануть грамматику выше (т.е. зовя) меня.
Я пытаюсь написать сленг для Раку без сигил.
Так что я хочу nogil
токен, соответствующий чему угодно <?>
чтобы вернуть NqpMatch, который преобразует: $<sigil>.Str
в '$'.
В настоящее время мой токен-сигил выглядит так
token sigil {
| <[$@%&]>
| <nogil> { say "Nogil returned: ", lk($/, 'nogil').Str; # Here It should print "$"
}
}
token nogil-proxy {
| '€'
| <?>
{log "No sigil:", get-stack; }
}
И метод с этим должен вернуть NQPMatch
с методом Str
перезаписанный
method nogil {
my $cursor := self.nogil-proxy;
# .. This si where Nqp expertise would be nice
say "string is:", $cursor.Str; # here also it should print "$"
return $cursor;
}
Неудачная попытка:
$cursor.^cache_add('Str', sub { return '$'; } );
$cursor.^publish_method_cache;
for $cursor.^attributes { .name.say };
for $cursor.^methods { .name.say };
say $cursor.WHAT.Str;
nqp::setmethcacheauth($cursor, 0);
В настоящее время большинство моих тестов работают, но у меня проблемы с объявлениями без моего (с no strict
) нравиться my-var = 42;
потому что они рассматриваются как вызов метода.
@Arne-Sommer уже сделал пост и статью. Это тесно связано. Но этот вопрос направлен на:
Как мы можем настроить возвращаемое значение токена времени компиляции, а не как его объявить.
1 ответ
Введение: ответ, на который указал @JonathanWorthington:
Кратко: используйте мета-функцию mixin. (И НЕ, но требуетcompose
метод.)
Демо:
- Создайте объект NQPMatch, получив другой токен: здесь токен
sigil-my
вызванныйself.sigil-my
. - Использовать
^mixin
с ролью
method sigil { return self.sigil-my.^mixin(Nogil::StrGil); }
Контекст: полный воспроизводимый код:
Итак, вы можете увидеть, что это за тип sigil-my
а также Nogil::StrGil
. Но я сказал вам: токен (больше, чем метод) и роль (неустановленные классы).
role Nogil::StrGil {
method Str() {
return sigilize(callsame);
}
}
sub EXPORT(|) {
# Save: main raku grammar
my $main-grammar = $*LANG.slang_grammar('MAIN');
my $main-actions = $*LANG.slang_actions('MAIN');
role Nogil::NogilGrammar {
method sigil {
return self.sigil-my.^mixin(Nogil::StrGil);
}
}
token sigil-my { | <[$@%&]> | <?> }
# Mix
my $grammar = $main-grammar.^mixin(Nogil::NogilGrammar);
my $actions = $main-actions.^mixin(Nogil::NogilActions);
$*LANG.define_slang('MAIN', $grammar, $actions);
# Return empty hash -> specify that we’re not exporting anything extra
return {};
}
Примечание: это открывает дверь к большему количеству проблем (на что также указывают комментарии к вопросу) -> -0fun!