使い慣れた本(続)

使い慣れた道具というものは捨てがたい。もう自分の手足の一部だといってもいいぐらいである。これは常時手近に置いて参酌する本についてもあてはまる。そんな本は手に持つだけで、どこにどんなことが書いてあるかということがもう感覚的にわかるからである。これは辞典的(または事典的)に使える本に特に顕著である。本の版が新しいものに変わったからといって、ホイホイとそちらの方に乗り換えることができないのは、その「感覚」が違ってしまい、結果的に使いにくくなるからである。

そんな本としてよく見ているものに、Larry Wall,Tom Christiansen,Randal L.Schwartz「プログラミングPerl 改訂版」(O'REILLY)がある。Perl開発者が書いたものでこの世界の古典である。この本はすでに「プログラミングPerl 第3版 VOLUME1」、「プログラミングPerl 第3版 VOLUME2」と2分冊になった新版が出ている。そうなると、1冊の本が別の1冊の本として新版になった場合と比べると「どこにどんなことが書いてあるか」がほとんどわからなくなる。それで1冊で全体が見渡せるので、相変わらず古い方を見てしまうという「弊」に「安住」してしまうことになる。自戒。

改訂版第3版 Vol.1第3版 Vol.2

最近気がついた、その新旧の差の例である。たとえば、何かの割合(パーセント)を小数第2位まで表示したいという場合がある。これは表示幅の指定の問題である。具体的には「*」の使い方である。これはPerlのバージョンによって違いがあるようである。

プログラミング my $nTotal = 97; my $nAccess = 139; my $nPart = 0; my $mx = 7; my $sd = 4; $nPart = $nTotal * 100 / $nAccess; printf ("検索終了 : $nTotal 件です (全件数 $nAccess のうちの %5.2f パーセント)。<br>\n", $nPart); # 検索終了 : 97 件です (全件数 139 のうちの 69.78 パーセント)。 print "<br>\n"; printf ("検索終了 : $nTotal 件です (全件数 $nAccess のうちの %*.*f パーセント)。<br>\n", $mx, $sd, $nPart); # これでも表示される。

EXECUTE
上のサンプルの実行例(labo_0007)


プログラミングPerl 改訂版

これはPerl 5.0準拠ということになっている。
printf, sprintf関数では「*」は使えない
「プログラミングPerl 改訂版」230pによれば、printf関数については、「この関数は、フィールド幅指定子「*」がサポートされていない点を除けば、Cライブラリ関数printf(3)fprintf(3)と同じ働きをする。」となっている。
また、sprintf関数については、「フィールドの長さに*を指定することはできない。」(同書256p)となっている。
フィールドの長さに*を指定することはできない。しかし、次の例のように、FORMAT中にフィールドの長さを直接埋め込んでしまえば、同じことがたやすく実現できる:
$width = 20; $value = sin 1.0;
foreach $precision (0..($width-2)) {
    $output_arr[$precision] = sprintf "%${width}.${precision}f", $value;
}
- Larry Wallほか著「プログラミングPerl 改訂版」(O'REILLY)256p -
ただし、これらの記述は下記の「第3版」には書かれていない


プログラミングPerl 第3版

これはPerl 5.6準拠ということになっている。
printf,sprintf関数では「*」は使える。要するに、正反対である(コペルニクス的転回である)。
「プログラミングPerl 第3版」では、printf,sprintf関数には上のような「*」に関する記述はない。その代わり次のような記述がある。
フラグの中で数値の代わりに、アスタリスク("*")を使うことができる。その場合、Perlは引数リストから次の引数を取り出して、それを数値の指定(つまり、フィールド幅または精度)として扱う。"*"によって得られたフィールド幅が負であれば、"-"フラグと同じ効果-つまり左寄せ-を持つ。
- Larry Wall,Tom Christiansen,Jon Orwant「プログラミングPerl 第3版 VOLUME2」(O'REILLY)949p -
【標語】たまには新鮮な空気を吸おう。

- 2018/07/04 -


しかし、ここを次のようにするダサイ方法はちょっと使う気がしない。ただし、市販の入門書は程度の低いパソコン・ライターがバカを相手に書いたものだからそんな例が出ているが、ここでは使わない。

printf( "n = %*.*f\n", "4", "2", "3.1415926535897" );

このような使い方は「*」の部分を定数と置き換えても問題はないものである。そのほうが普通である。本来の「*」は、そこに変数の表す値を指定して、そのフィールド幅をコロコロと変えていくという使い方をするものである。