変数名で動作を変える。 [プログラミング]
void output(const char* mes);
というインターフェースを持つ関数がありました。
この関数を呼ぶと、引数で指定した文字列を表示します。
ぶっちゃけ、こんな関数です。
void output(const char* mes) { puts(mes); }
で、文字列は定数で定義されていて、output
関数は定数名を指定して呼び出すことになっていました。
const char* MES1 = "メッセージ1"; const char* MES2 = "メッセージ2"; const char* ERR_MES1 = "エラーメッセージ"; void func() { output(MES1); output(MES2); output(ERR_MES1); }
そんなある日のこと………。
「大事な仕様を見落としていた。普通のメッセージは標準出力だけど、エラーメッセージは標準エラー出力に出さなきゃいけなかったんだ」
あー、そうですか。
「で、もうコーディングは進んじゃっているから、output関数の中身を修正するだけで対処したいのね」
は?
引数が1つしかないのに、どうやってエラーメッセージかどうか判定しろと?
「エラーメッセージの定数名は必ず『ERR_』で始まることになっているから」
えっ……、と
標準エラー出力に出力する output_err
関数を作って、ソースコード中の output(ERR_
を output_err(ERR_
に全置換したら良いですか?
「それは困る。そんな事をしたらoutput
関数の仕様を見落としていたことがバレるではないか。私の立場も考えてくれよ。なんとしてもoutput
関数を修正するだけで済ませるのだ。それ以外1文字たりとも書き換えることは許さん。output
関数の引数が、ERR_
で始まる定数なら、標準エラー出力に出力するのだ」
むちゃくちゃ言いよるな。
ちなみに上のやり取りは8割くらいフィクションです。
そんな訳で、
引数で指定した定数名がERR_
で始まるかどうかで処理を変えるoutput
関数を作ることになりました。
別の人は「そんなものは出来ん」と突っぱねたそうですが。
#define output(MES) \ if (strncmp(#MES, "ERR_", 4) == 0) { \ fputs(MES, stderr); \ fputs("\n", stderr); \ } else \ puts(MES)
const char* MES1 = "メッセージ1"; const char* MES2 = "メッセージ2"; const char* ERR_MES1 = "エラーメッセージ"; void func() { output(MES1); output(MES2); output(ERR_MES1); }
これで、"メッセージ1"、"メッセージ2" は標準出力へ、"エラーメッセージ"は標準エラー出力に出力できます。
後日談。
「エラーメッセージの出力は output_err
関数を使ってね」と言う事になりました。
今日の二冊 | |
|
コメント 0