PostScript 字典有什么用?如何知道我是否需要它?

PostScript 字典有什么用?如何知道我是否需要它?

考虑以下代码,

\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不同于\WithDictonly in 的tx@Dict是,in\WithoutDict不使用。Christoph在tx@Dic\WithDict他的回答在这里。我真的不明白我为什么需要它。

所以问题是,

  1. PostScript 词典有何用途?
  2. 如何在一个简单但不平凡的例子中使用它?
  3. 我怎么知道我是否需要它?

希望答案可以作为速成教程。

答案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。数组、字典甚至字符串都可以与getandput运算符一起多态使用。

相关内容