考虑以下代码,
\documentclass[pstricks,border=12pt]{standalone}
\usepackage{pstricks-add}
\psset{linecolor=red}
\pstVerb
{
/updateCP {2 copy CPy add /CPy ED CPx add /CPx ED} bind def
/updateA {1 sub sqrt 1 exch atan Angles add /Angles ED} bind def
}
\def\WithoutDict{%
\begin{pspicture}[showgrid](-5,-5)(5,5)
\multido{\io=1+1}{15}
{%
\pstVerb{/Angles 0 def /CPx 1 def /CPy 0 def}% reset
\def\points{(0,0)(1,0)}% reset
\multido{\ii=1+1}{\io}{\xdef\points{\points(!1 \ii\space updateA Angles PtoC updateCP)}}
\expandafter\psrline\points
\psline(!CPx CPy)
}
\end{pspicture}}
\def\WithDict{%
\begin{pspicture}[showgrid](-5,-5)(5,5)
\multido{\io=1+1}{15}
{%
\pstVerb{tx@Dict begin /Angles 0 def /CPx 1 def /CPy 0 def end}% reset
\def\points{(0,0)(1,0)}% reset
\multido{\ii=1+1}{\io}{\xdef\points{\points(!1 \ii\space updateA Angles PtoC updateCP)}}
\expandafter\psrline\points
\psline(!CPx CPy)
}
\end{pspicture}}
\begin{document}
\WithoutDict
\WithDict
\end{document}
产生以下输出。
问题
\WithoutDict
不同于\WithDict
only in 的tx@Dict
是,in\WithoutDict
不使用。Christoph在tx@Dic
\WithDict
他的回答在这里。我真的不明白我为什么需要它。
所以问题是,
- PostScript 词典有何用途?
- 如何在一个简单但不平凡的例子中使用它?
- 我怎么知道我是否需要它?
希望答案可以作为速成教程。
答案1
Postscript 字典实现了命名空间的概念,允许控制变量的可见性。要查看 Postscript 解释器的命令行输出,请运行ps2pdf
生成的 PS 文件dvips
。
\documentclass{article}
\usepackage{pstricks}
\begin{document}
Dictionaries implement the concept of name spaces to control variable visibility
\pstVerb{
/myvar (hello!) def % `global' definition
/mydict 1 dict def
mydict begin % open namespace
/myvar (goodbye!) def % `local' definition
myvar == % print local value
end % close namespace
myvar == % print global value
mydict begin % reopen name space
myvar == % print local value once more
end
}
\end{document}
如果您不知道要将 PSTricks 包中的哪些现有字典放入字典堆栈,您可以随时在自己的新字典中定义变量。在需要时,将您的字典放入字典堆栈,使其成为当前字典(并且其中定义的变量可用)。
字典和操作数堆栈是分开的。将字典放入和弹出字典堆栈不会影响操作数堆栈:
\documentclass[pstricks,border=12pt]{standalone}
\usepackage{pstricks-add}
\begin{document}
\psset{linecolor=red}
\pstVerb
{
/updateCP {2 copy CPy add /CPy ED CPx add /CPx ED} bind def
/updateA {1 sub sqrt 1 exch atan Angles add /Angles ED} bind def
}
\begin{pspicture}[showgrid](-5,-5)(5,5)
\multido{\io=1+1}{15}
{%
\pstVerb{
/mydict 1 dict def % roll your own dict
mydict begin % put it on top of the dict stack
/Angles 0 def /CPx 1 def /CPy 0 def %define your variables
end % pop your dict from the dict stack (it doesn't get lost!)
}% reset
\def\points{(0,0)(1,0)}% reset
\multido{\ii=1+1}{\io}{\xdef\points{\points(!1 \ii\space
mydict begin % make your dict the current (i.e. top-level) one by
%putting it on the dict stack
updateA Angles PtoC updateCP % work on your variables
end % remove it from the dict stack, point coordinates remain on
% the operand stack
)}}
\expandafter\psrline\points
\psline(!mydict begin % make your dict the current dict
CPx CPy
end) % and remove it from dict stack, CPx CPy still on the operand stack
}
\end{pspicture}
\end{document}
答案2
更一般地,postscript 字典是一个关联数组。它可以关联任何类型的对象对,但也有少数例外。它不能使用对象nulltype
作为键,因为它使用 来null
标记数组中的空位。它隐式地将stringtype
键转换为nametype
。
但它也可以与数字键一起使用来实现记忆函数。它可以使用整数键来表示稀疏字符编码集,或者更一般地表示字符串重写系统的替换规则。它们可以保存递归函数的局部变量。它们可以用方法(甚至是纯虚拟方法)来实现封装的对象。
从级别 2 开始,字典将自动增长以容纳其内容。这使得它们非常适合实现增长数组,方法是使用与数组索引一样工作的整数键。
/dictarr <<
0 5
1 7
2 4
>> def
/regularr [
5
7
4
] def
dictarr 1 get
regularr 1 get % 7 7
dictarr dup length 9 put % append to dict-array
/regularr [ regularr aload pop 9 ] def % append to regular-array
要增大常规数组,您必须分配一个新数组,而向字典中添加一个键值对则非常便宜,因为内部数组的增长在设计上是在多次调用中摊销的。
对于这两种样式,最后一个元素的“索引”是length 1 sub
。数组、字典甚至字符串都可以与get
andput
运算符一起多态使用。