Как правильно объясняет joojaa, LOCAL
не определяется ничем, что нормально, поскольку он заменен перед выполнением. Он анализирует исполняемое имя во время построения тела процедуры (массива), и его использование здесь - это просто выделить слот в массиве. Это может быть любой тип, и я часто видел (и писал) { 0 begin ...}
с той же целью. Использование имени позволяет предоставить более семантическую информацию для читателя, читающего код. Я также видел, что это написано { DICT begin ... }
Here в моих матричных функциях, я назвал его STATICDICT
, по-видимому.
Существует соглашение об использовании всех верхних регистров для любых мета-синтаксических таких жетонов. Это токен типа natetype, но мета-синтаксически он ссылается на объект dicttype, который будет заполнен позже. Нет необходимости (и даже какого-либо механизма) заявлять, что вы делаете в интересах переводчика, но многое можно получить, предпочтя DICT
за 0
. Опять же, поскольку он будет полностью заменен, вы также можете использовать буквальное имя /LOCAL
, чтобы попытаться, idunno, освободить следующий noob, чтобы прочитать ваш код из wild-goose-chase в поисках того, где определено LOCAL
?? С этой целью я также написал просто DUMMY
для токена для заполнения в конце. Я полагаю, что выбор среди этих терминов является вопросом стиля или аудитории или каким-то другим нематериальным качеством. вздох ... или просто вопрос контекста.
Существует еще один стиль, который хорошо подходит для создания динамических замещений в процедурных телах. Размещая словарь на dictstack и назвав его (внутри себя, так что это замкнутое пространство имен), мы можем обратиться к нему с //immediate
именем
4 dict begin
/mydict currentdict def
/proc {
//mydict begin
...
end
}
, а затем удалить словарь перед определением.
end def
Таким образом, определение порядка обычно (в словаре внешнего уровня (неименованный здесь, по-видимому userdict
)), но со словарем встроенным по имени, от того, был доступен под этим именем в то время как тело процедуры было отсканированы.
Это может быть распространено на большее количество процедур, использующих один и тот же частный словарь, путем подтасовки dict из стека для каждого определения.
/enddefbegin { currentdict 3 1 roll end def begin } def
4 dict begin
/mydict currentdict def
/proc1 {
//mydict begin
...
end
} enddefbegin
/proc2 {
//mydict begin
...
end
} enddefbegin
end
enddefbegin end
в конце, конечно, может быть упрощено до end def
.
Одно предостережение. Созданный таким образом словарь рекурсивно содержится с собой. Не пытайтесь распечатать его с помощью оператора ghostscript ===
!
Я понятия не имел, что программа PS может или может изменить исполняемый массив. Это непростительно. Отличный ответ, спасибо! –
Эй, подожди. Это означает, что PostScript похож на LISP: _Code - это просто данные, которые вы выполняете. И манипулируйте, если хотите. –
@WayneConrad Да – joojaa