问题描述
这很好
/posX 200 def
posX 100 moveto
这不起作用
/positions 1 dict def
positions begin
/posX 200 def
end
positions posX get 100 moveto
经过数小时的奋斗,我偶然发现了使其正常工作的方式
positions /posX get 100 moveto
有人可以解释为什么在使用字典键时需要保留斜杠吗?
我查看了参考手册并在网上搜索,找不到任何解释(我确定它在某个地方,我根本找不到它)。
特别是如果有人可以使我指向参考手册中描述(对我来说是什么)的部分的行为,我将不胜感激。
解决方法
很好的字典键不需要,但需要使用“斜杠”,但是我们将回到这一点。
正斜杠引入了文字名称对象,相同的名称但没有'/'也引入了名称,但是在这种情况下,它是可执行名称。 / p>
您可以在第三版PLRM的第36页上找到它。第3.3.2节“对象的属性”实际上从第35页开始,但文字和可执行属性在第36页进行了描述:
•如果名称以/开头,则为文字;如果名称开头,则为可执行文件 不是。
在页面顶部,定义了解释器遇到文字或可执行对象时的动作:
•如果对象是文字,则解释器将其严格视为数据 并将其压入操作数堆栈,以用作某些操作数 后续运算符。
•如果对象是可执行的,解释器将执行它。
因此,当您将/ posX放置为文字名称对象,并且解释器将其视为数据时,将其压入操作数堆栈以供以后使用。当您放置posX作为可执行文件的名称对象时,解释器将尝试执行它。
仍然在同一页上(36),我们看到:
•执行可执行文件名称会使它在 当前的字典上下文以及要执行的关联值。
因此,在遇到/ posX时,解释器会创建一个名称对象'posX'并将其放置在操作数堆栈中。遇到posX时,解释器会尝试在当前词典中查找“ posX”作为键。
您的代码是:
/positions 1 dict def
positions begin
/posX 200 def
end
positions posX get 100 moveto
您已经在字典“位置”上使用了begin
,因此它已经是当前字典。这意味着您可以(而不是通常在PostScript中,可以)使用get
从“位置”中检索值:
/positions 1 dict def
positions begin
/posX 200 def
posX 100 moveto
end
显然缩进只是为了强调,以显示词典的最新位置。
现在转到旁注。字典键不必是名称!它们几乎总是如此,但是有时使用“其他”作为关键很有用。举一个人为的例子,我想知道一个文档中所有字体使用了多少文本。
%!
/MyDict 20 dict dup def begin
/FontNumbers 20 dict def
/old_show show load def
/show {
currentfont dup
FontNumbers known {
dup FontNumbers get 1 add FontNumbers exch put
}{
FontNumbers exch 1 put
} ifelse
old_show
} bind def
end
现在,每次使用“ show”时,我们都会在当前词典中查找“ FontNumbers”。然后,我们使用currentfont
返回的字体字典作为键,并查看该键是否存在于字典中。如果是我们get
的关联值,则再次使用当前字体字典作为键,将新值加1并put
。如果找不到键,那么我们将键/值对放在其中值是0且键是当前字体字典的地方。
注意!我没有尝试过该代码,它可能会出错,这只是为了说明这一点,字典中的键不必是名称,它可以是任何类型的对象。参见PLRM的第41页,第3.3.9节“字典对象”。