我有一个简单的函数,有两个变量
/func {
/var1 exch def
/var2 exch def
... process ...
} def
(var2)(var1)func
我想让var2成为可选项。但是,如果不提供var2,则会导致stackunderflow错误。如果堆栈不为空,我怎样才能使if语句捕获var2,如果堆栈为空,可能会分配一个默认值。
像
这样的东西(Stack is no empty) {/var2 exch def}{/var2 (default) def} ifelse
答案 0 :(得分:4)
count
运算符计算堆栈上的操作数数量。您可能希望使用[
在堆栈上添加标记,然后使用counttomark
代替。当您从其他例程调用例程时,这可以避免因操作数被遗留或尚未使用而感到困惑。当然,这意味着你必须在堆栈上提供[
作为操作数。
另一种常用的方法是使顶部操作数为一个整数,计算其他操作数的数量。
答案 1 :(得分:2)
另一种方法是传递命名参数的字典。修改你的例子......
/func { %<<params>>
%begin currentdict /var2 2 copy known not {(default) put}{pop pop} ifelse
<</var2(default)>> copy begin
% ... process ...
end } def
<<
/var1 (var1)
/var2 (var2)
>> func
答案 2 :(得分:1)
另一种常用方法是使用最顶层操作数的类型来确定要查找的操作数的数量。
这是实现执行此操作的rotate
运算符的一种方法:
/rotate { % angle ([matrix])? rotate -|[matrix]
dup type /arraytype ne
{ true exch matrix } % no array: create array, concat later
{ false 3 1 roll } % array: do not create, do not concat later
ifelse % bool angle matrix
dup 0 % bool angle matrix matrix 0
3 index cos put % bool angle matrix
dup 1 3 index sin put % bool angle matrix
dup 2 3 index sin neg put % bool angle matrix
dup 3 4 3 roll cos put % bool matrix
exch { concat } if % [matrix]
} def