スクリプト言語間における「lexical closure」の違い─PostScript 版
ネタ元は スクリプト言語間における「lexical closure」の違い、それともプログラムの違い? - karasuyamatenguの日記。(スクリプト言語間における「lexical closure」の違い ― Squeak Smalltalkの場合 - Smalltalkのtは小文字です経由)PostScript なら、数行入れ替えるだけで Perl 風にも Python 風にもなります。
PostScript は動的スコープなので、まず lexical closure を自作する必要があります。Perl 風、 Python 風共通です。
%!PS /closure{ [ countdictstack array dictstack [ exch{ dup systemdict eq{ cleartomark mark systemdict }if }forall ]{ begin }/forall cvx counttomark 2 add -1 roll /stopped cvx 4 index length{ end }/repeat cvx { stop }/if cvx ]cvx }def
文字列結合オペレータも作っておきます。
/strcat{ 3 dict begin /str2 exch def /str1 exch def /buf str1 length str2 length add string def str1 buf copy pop buf str1 length str2 putinterval buf end }def
for ループの中で dict begin ... end すると、繰り返し毎に別のスコープが作られ、Perl 風になります。
/closures 5 array def 0 1 4{ 2 dict begin /i exch def /localvar (foo) i ( ) cvs strcat def closures i { localvar }closure put end }for closures{ exec = }forall
$ gsnd -q -dBATCH colv.ps foo0 foo1 foo2 foo3 foo4
for ループの外で dict begin ... end すると、変数のスコープがループ中で共通になり、Python 風に振る舞います。
/closures 5 array def 2 dict begin 0 1 4{ /i exch def /localvar (foo) i ( ) cvs strcat def closures i { localvar }closure put }for end closures{ exec = }forall
$ gsnd -q -dBATCH colv.ps foo4 foo4 foo4 foo4 foo4