Есть ли способ безопасно переопределить символ?

9

Я часто экспериментирую с REPL, и я скажу что-то вроде:

subset Bar of Int where * %% 57;

Затем я Barнемного поиграюсь с проверками на наличие вещей.

Все устраивает, пока я не пойму, что хочу изменить определение Bar.

Если я просто переопределю Bar, я получу Redeclaration of symbolисключение.

Я попытался использовать MONKEY-TYPINGи augmentвот так:

use MONKEY-TYPING;
augment subset Bar of Int where * %% 37;

Но это привело меня к той же ошибке.

Зачем мне это? Таким образом, я могу перебрать определения своего подмножества (или класса, или другого символа), одновременно используя уже набранные тесты, которые есть в моей истории.

daotoad
источник

Ответы:

3

Я думаю, что REPL делает часть своей магии, EVALвводя каждый новый вход в новую вложенную лексическую область видимости. Таким образом, если вы объявляете вещи с помощью myзатем, вы можете скрывать их с помощью объявлений, введенных позже:

my subset Bar of Int where * %% 57;
sub take-Bar(Bar $n) { say "$n is Bar" }
take-Bar 57;

my subset Bar of Int where * %% 42;
sub take-Bar(Bar $n) { say "$n is Bar" }
take-Bar 42;

Если вы опустите my, тогда будут использоваться объявления for subsetи , и поскольку фактически + добавление символа во вложенный пакет ...; Оказывается, если вы удалите символ из пакета, вы можете затем снова затенять его:classourourmy

subset Bar of Int where * %% 57;
GLOBAL::<Bar>:delete;
subset Bar of Int where * %% 42;
42 ~~ Bar;

ПРИМЕЧАНИЕ: эти результаты только из моих экспериментов в REPL. Я не уверен, есть ли другие неизвестные побочные эффекты.

cowbaymoo
источник
8

У этого REPLесть свои недостатки. Это сложная конструкция EVALутверждений, которые пытаются работать вместе. Иногда это не сработает.

Я думаю, лучшее, что мы могли бы сделать, это ввести команду REPL, которая заставила бы ее забыть обо всем, что она делала раньше. Патчи приветствуются! :-)

Элизабет Маттийсен
источник
Так что, если я правильно понимаю, я был на правильном пути с use MONKEY-TYPING и , augmentно они не работают должным образом в РЕПЛЕ (пока?) , Потому что нужно много магии и уток ленты.
daotoad
1
AFAIK, вы можете использовать только дополнения, чтобы добавить материал в класс. То, что вы пытаетесь сделать, это заменить собой подмножество .
Элизабет Маттийсен
1
@daotoad Чтобы заменить, вы можете использовать supersede , но я считаю, что в настоящее время это остается невыполненным.
user0721090601
1
Supersede все еще не реализован, но в любом случае это будет работать только на уровне установленных модулей. Функция замены должна позволять модулю указывать, что он должен быть загружен вместо другого модуля / версии. Следовательно, это подсказка для CompUnitRepo, когда его спрашивают, может ли он предоставить данный модуль.
Элизабет Маттийсен,