Macro PPRINT-LOGICAL-BLOCK
pprint-logical-block
(
stream-symbol object &key
prefix per-line-prefix suffix)
declaration* form* => nil
stream-symbol - ストリーム変数指定子
object - オブジェクト。評価されます。
prefix - 文字列。評価されます。標準の動作は複雑なので説明を参照。
per-line-prefix - 文字列。評価されます。標準の動作は複雑なので説明を参照。
suffix - 文字列。評価されます。デフォルトは空文字。
declaration - 宣言式。評価されません。
form - 暗黙のprogn
プリントを行う際の論理ブロックのグルーピングを行います。 論理ブロックは、ストリームに対して印刷を行い、 そのストリームの値はstream-symbolによって示された変数の値になります。 formを実行している間、 その変数にはプリティプリントのストリームが束縛されており、 そのストリームは出力の配置についての決定を行い、 その結果を宛先の出力ストリームに送信します。 標準の印刷関数の全て(例えばwrite
, princ
, terpri
)は、 プリティプリントのストリームへ印刷を出力するために使用できます。 プリティプリントのストリームへの全ての出力は、 ただ論理ブロック内にあるもののみ扱われます。
prefixは、論理ブロックの開始の前に印刷されるプレフィックスを指定します。 per-line-prefixは、ブロックの前と ブロック内の新しい各行の始まりに印刷されるプレフィックスを指定します。 :prefix
と:per-line-prefix
引数は、互いに排他的です。 もし:prefix
と:per-line-prefix
がどちらも指定されなかったら、 prefixが空文字であると仮定されます。
suffixは、ちょうど論理ブロックのあとに 印刷されるサフィックスを指定します。
objectは普通はリストであり、 ボディ部であるformにおいて印刷のために使用されます。 もしobjectがリストではなかったとき、 それはwrite
によって印刷されます (これにより、不正な引数に直面しても 堅牢な印刷関数を簡単に書くことができます)。 もし*print-circle*
がnil
ではなく、 objectがコンスへ循環(あるいは共有)した参照があったとき、 適切な#n#
という印が印刷されます (これにより、循環と共有の省略形を完全にサポートした 印刷関数を簡単に書くことができます)。 もし*print-level*
がnil
ではなく、 論理ブロックが、複数の論理ブロック内において 動的にネストされた深さが*print-level*
より大きいとき、 #
が印刷されます。 (これにより、深さの省略形を完全にサポートした 印刷関数を簡単に書くことができます)。
もし上記の3つの状況のどれかが生じたとき、 示された出力がstream-symbol上に印刷され、 ボディ部のformは:prefix
と:suffix
の印刷とともにスキップされます (ボディ部のformがリストの印刷を担当しないときは、 引数objectにnil
指定することで、 上記の最初の2つのテストをオフにすることができます)。
さらにpprint-logical-block
の引数objectは、 標準印刷関数(write
, print
, princ
, pprint
や、 標準のformat
指示子の~A
と~S
(そして~W
も)の引数と同様に) (必要であれば)循環と要求のチェックが全てにおいて行われます。 しかし、そのようなチェックは write-line
, write-string
, そしてwrite-char
の引数か、 format
によるリテラルテキストの出力については行われません。 これらの結果から、 もし何らかのリテラルテキストを出力する際に 循環と共有のチェックをして欲しくないときは、 後者の関数のうちのひとつを使用するべきです。
pprint-logical-block
のボディ部であるformは、 周囲の環境上において何も副作用を実施するべきではありません。 例えば、そのスコープ内において束縛されていない変数に代入してはいけません。
なし。
なし。
:suffix
, :prefix
, :per-line-prefix
のどれかが指定されたものの 文字列に評価されなかったときは型type-error
のエラーが発生します。
:prefix
と:per-line-prefix
の両方が使用されたときはエラーが発生します。
pprint-logical-block
は動的エクステントを持っており、 プリティプリントのストリームを生成します。 もしそのエクステントの外側において 生成されたプリティプリントのストリームへ 出力しようとしたときの結果は未定義です。
また、そのエクステントの内側において、 元となる宛先のストリームに直接出力を送信したときの結果は指定されていません。
pprint-pop
, pprint-exit-if-list-exhausted
, 22.3.5.2. チルダ<
: 論理ブロック
*print-pretty*
の値がnil
のときに pprint-logical-block
マクロを使用するひとつの理由は、 ドットリストのチェックを行うということ、 また同様に(pprint-pop
によって) *print-level*
か*print-length*
を超過したかどうかの チェックを行うということです。
循環と共有の検出は、プリティプリンターによって 要求された出力を二回行うことで実現します。 最初の実行では循環と共有を検出し、実際の文字の出力は抑制されます。 二回目の実行では、 #n=
と#n#
のマークを適切な位置に挿入し、そして文字を出力します。 これが、なぜ副作用を制限する必要があるかという理由です。 この制限に従うと、 pprint-logical-block
のボディ部formにおいて、 リストの内容を出力していく際に 通常のpop
のかわりにpprint-pop
を使用することにより、 実装が容易になります。