hkoba blog

プログラマーです。プログラミング言語ミーハーです。ツッコミ歓迎です。よろしくどうぞ(能代口調)

再帰globパターン **/ の元祖は zsh なのか、調べてみた

今日 @satoh_fumiyasu さんのこんなツイートを見かけました。

私もずっと気になっていたので、この機会に調べてみました。

最初は ..../ だった!

当時のソース公開は usenet 経由だったよな、というわけで groups.google.com で zsh を検索すると、Zsh-1.0 の公開時のアナウンス と、 ソース が出てきました。

アナウンスの中では zsh の機能の由来を From ksh, From tcsh, From bash と細かく挙げているのですが、 再帰globパターンは『その他』として別扱いされています。

Other stuff:

        - recursive directory search in filename generation (for example,
          "ls ..../*.c" lists all .c files in the hierarchy)

これによると Zsh-1.0 では、 **/ のような再帰 glob を ..../ と書いていたのですね。 この書き方は翌年リリースされた Zsh-2.00 でも変わらないようです。

Zsh-2.1 で ****/ に変わった

Zsh-2.1 の README の Modification history に、初めて ****/ の言及が出てきます。

Modification history:
0.03-1.0:
        - "..../" is now "****/".  I know this isn't backward compatible,
          but I had no choice; the string "..../" was unquotable.

0.03-1.0 とありますが、恐らく 2.03 から 2.1 のことを指しているのでしょう。

Zsh-2.2 で **/ になった

そしてついに Zsh-2.2 の Modification history に、 **/ が出現します。

Modification history:

2.2.0-2.1.0:

o ls **/file is now equivalent to ls ****/file

時に、1992/05/14。 ここまでの経緯を見るに、zsh が元祖ではないか?と私には見えました。

なぜ ..../ や ****/ だったのか?

ところでなぜ最初、再帰glob は ..../ という長い書き方だったのでしょう? それは、どうやら、 実装に理由があったようです。

そもそも zsh**/ は、0個以上へのマッチ文字 # (正規表現のクリーネスターに相当)を使った書き方 (*/)# の省略形です。 (マニュアルを参照)

で、なんと、Zsh-1.0 のソースを読むと、 ..../ を直接 (*/)# へと置き換える^^、という実装になっていたのです。

gist.github.com

要するに、5文字で、ファイル名として滅多に使わないものという制約の中で、打ちやすいものを選んだのでしょうね。