デバッグ出力の「傾向と対策」
ここでは中身を調べたいものの“型”で分類して、それぞれの場合にどの命令を用いるべきかを記す。show 系の表示をしたい場合と print デバッグの出力(\write や \meaning を用いる)で用いる命令が異なるが、ここでは“show 系/print 出力系”の形式で示す。
マクロ \CS の定義内容を調べる → \show\CS/\meaning\CS
\def\xTerm#1#2{\textsf{#1}(\textit{#2})}
%\newcommand*\xTerm[2]{\textsf{#1}(\textit{#2})} % LaTeX の命令定義
\show\xTerm %==> > \xTerm=macro:
% #1#2->\textsf {#1}(\textit {#2}).
\typeout{\meaning\xTerm} %==> macro:#1#2->\textsf {#1}(\textit {#2})トークン列(文字列)変数 \CS の内容を調べる:\CS がマクロである → \show\CS/\meaning\CS(単純(完全展開可能)な文字列しか扱わないのなら \CS でもよい)
\def\xx@mode{plain} % 文字列変数なマクロ
\show\xx@mode %==> > \xx@mode=macro:
% ->plain.
\typeout{\meaning\xx@mode} %==> macro:->plain
\typeout{mode=\xx@mode} %==> mode=plainトークン列(文字列)変数 \CS の内容を調べる:\CS がトークン列レジスタである → \showthe\CS/\the\CS(それ以上展開されない)
\newtoks\xx@mode \xx@mode{plain} % 文字列変数なレジスタ
\showthe\xx@mode %==> > plain.
\typeout{(\the\xx@mode)} %==> (plain)整数変数 \CS の値を調べる:\CS が整数レジスタである → \showthe\CS/\the\CS
\newcount\xx@max \xx@max=42
\showthe\xx@max %==> > 42.
\typeout{max:\the\xx@max} %==> max:42
\newlength{\phewwidth}\setlength{\phewlength}{2pt}% LaTeX の長さ命令
\showthe\phewlength %==> > 2.0pt.
\typeout{\the\phewlength} %==> 2.0ptLaTeX カウンタ CTR の値を調べる → \showthe\value{CTR}(または \showthe\c@CTR)/\arabic{CTR}(または \the\c@CTR)
- カウンタ
CTRの実態は整数レジスタc@CTR。 \arabicや\Romanは完全展開可能なのでそのまま print 出力に使える。
\newcounter{maxglemish} \setcounter{maxglemish}{42} % LaTeX のカウンタ
\showthe\value{maxglemish} %==> > 42.
\showthe\c@maxglemish %==> > 42.
\typeout{\arabic{maxglemish}} %==> 42
\typeout{\Roman{maxglemish}} %==> XLII整数定数 \CS の値を調べる:\CS が chardef である → \showthe\CS/\the\CS
- 要するに、整数・寸法・グルー型の内部値として通用するものなら
\showthe/\theでよい。
\chardef\xx@max=42 % chardef で定数定義
\showthe\xx@max %==> > 42.
\typeout{max:\the\xx@max} %==> max:42ブール変数(スイッチ) \ifCS の値を調べる → \show\ifCS/\meaning\ifCS
- ifthen パッケージの
\newboolean{CS}や etoolbox パッケージの\newbool{CS}で定義された場合も同じ。 - ただし、この方法でテストすると不均衡の
\ifが発生する。これを防ぐには、etoolbox を使って、\csshow{ifCS}や\ifbool{CS}TF(TかFに展開される)とするか、または\@gobble\fiを適宜挿入する。 - etoolbox の
\newtoggle{CS}で定義されたブール変数の場合は、素直に\iftoggleで頑張る。
\newif\ifxx@draft \xx@drafttrue
% \newboolean{xx@draft}\setboolean{xx@draft}{true} %ifthen パッケージ
% \newbool{xx@draft}\booltrue{xx@draft} %etoolbox パッケージ
\show\ifxx@draft \@gobble\fi %==> > \ifxx@draft=\iftrue.
\csshow{xx@draft} %==> > \ifxx@draft=\iftrue.
\typeout{\meaning\ifxx@draft\@gobble\fi} %==> \iftrue
\typeout{\ifbool{xx@draft}TF} %==> T暗黙の文字トークン \CS(文字に \let された制御綴)の値を調べる → \show\CS/\meaning\CS
\let\xx@align=c % l=左,c=中央,r=右, の様に決める
\show\xx@align %==> > \xx@align=the letter c.
\typeout{align:(\meaning\xx@align)} %==> align:(the letter c)マクロの引数 #1 として渡されたトークン列を調べる → \showtokens{#1} / \unexpanded{#1}(単純な文字列しか扱わないのなら #1 でもよい)
- TeX では、引数の扱いは“変数”(マクロ、レジスタ)のそれとは異なることに注意。
- 当該のマクロが展開された時に引数(#1、#2、…)は渡された引数のトークン列に置き換えられている。なので、「渡されたトークン列をそのまま出力する」
\showtokensを利用するのが正解。 - ちなみに、まだ e-TeX 拡張が使えなかった時代は、「
\def\ARGS{#1}\show\ARGS」のようにしていた。
\def\xx@some@proc#1{%
\showtokens{#1}% デバッグ
%...実際の処理
}
\xx@some@proc{{\TeX}はアレ} %==> > {\TeX }はアレ.マクロの引数 #1 に何か整数変数(レジスタ)が渡されている、という前提でその変数の値を調べる → \showthe#1 / \the#1
- さっき書いた通り、
#1は実際の引数(例えば\CS)に置き換わっている。なのでその前提で適切な命令を選ぶ。 - 他の「#1 に〜が渡されている前提で〜」というパターンも同じ。
\def\xx@some@proc#1{%
\showthe#1% デバッグ
%...実際の処理
}
\newcount\xx@ans \xx@ans=42
\xx@some@proc{\xx@ans} %==> > 42.
% (\showthe\xx@ans が実行される)マクロの引数 #1 に何か“整数”が渡されている、という前提でその値を調べる → \showthe\numexpr#1\relax / \the\numexpr#1\relax(または \number#1)
- “整数”なのは確かだが、変数(レジスタ)なのか定数(chardef)なのか即値(“
42”のような数字)なのかは不定である、という場合。e-TeX 拡張の\numexprを流用する。 - 同様に、寸法の場合は
\dimexpr、グルー値の場合は\glueexprを流用する。 - e-TeX 拡張がない場合、整数値の print 出力に限っては
\numberが使える。
\def\xx@some@proc#1{%
\showthe\numexpr#1\relax% デバッグ
%...実際の処理
}
\xx@some@proc{\m@ne} %==> > -1.
\xx@some@proc{"64} %==> > 100. %(16進表記)