Nov 20, 2009 14:47
А можно ли сделать пакет по свойствам похожий на пакет keyword?
Так, чтобы получилось, что наш пакет содержит любой символ и значением любого символа из этого пакета было бы, скажем, строковое представление этого символа?
> (symbol-value (ourpackage:any_symbol))
"any_symbol"
Leave a comment
Ну а вариант (symbol-value ourpackage:any_symbol) всегда даст динамическое глобальное значение переменной ourpackage:any_symbol. Чтобы это значение всегда была строка "any_symbol" нужно:
1. при первом обращении неявно создать такой символ. Это возможно, только с помощью reader-macro (как и в случае с : )
2. заблокировать возможность пользователям присваивать новое значение (т.е. при первом обращении объявлять его как константу, а при последующих не переопределять). Опять же все в рамках того reader-macro.
Можно попробовать написать его самому, ориентируясь на тот вариант, который я дал. Хотя он концептуально не совсем правильный, поскольку всё интернирование (создание символа) и присвоения ему значения должно происходить в read-time (а у меня оно переносится на runtime). Поэтому я немного доработал тот подход:
(set-dispatch-macro-character #\# #\^
(lambda (stream char arg)
(declare (ignore char arg))
(let* ((raw (read stream t nil t))
(str (princ-to-string raw)))
(eval `(progn (defconstant ,(intern str :strword) ,str)
(export (find-symbol ,str :strword) :strword)))
`(find-symbol ,str :strword))))
Однако тут есть определенная проблема, впрочем решаемая, с повторным объявлением константы. Ее решение is left as an excercise to the reader. ;)
Reply
Почему?:)
константы keyword ведь занимают только value cell символа
функции с именами-символами-из-keyword, вроде бы, никто определять не запрещает
Reply
но только такая функция будет вести себя также, как и обычная, т.е. ожидать от нее поведения
> (symbol-value (ourpackage:any_symbol))
"any_symbol"
можно при условии, что (например):
> (ourpackage:any_symbol)
'ourpackage:any_symbol
(та же последовательность рассуждений применима и к keyword-функциям)
Reply
Leave a comment