From: "H.Yamamoto" Date: 2004-01-08T19:41:05+09:00 Subject: [ruby-dev:22552] Re: can't require 山本です。 >At Thu, 8 Jan 2004 13:49:40 +0900, >H.Yamamoto wrote: >> もしも **/ とシンボリックリンクのチェックがタイムリーでなくていいのなら、 >> 上からマッチする順が下からマッチする順と同様に高速で、 >> デフォルトが上からマッチなので互換性も取れて、 >> Win32のパッチも今のままで問題なくなって、 >> なかださんのパッチでよさそうなんですけど、どうなんでしょうか。 >> (ただ、_WIN32のコードは外にだせるかも) > >名前を先にyieldしてからその中身を読むという動作上、ある程度はしょ >うがないような気がします。これをどうしても避けたいなら、今 >rb_w32_opendir()でやっているように一度全部読んでしまう以外には >ないかも知れません。しかし今度は、readdir()したときにはあったファ >イルがなくなったり、なかったものが増えていたりという可能性もで >てくるでしょうし。 この点については、誤解があるかもしれないので確認します。 Rev1.94では、 if (do_lstat(...) && S_ISDIR(...)) { glob_helper(...); } のように lstat の後すぐ glob_helper を呼んでいるので、 シンボリックリンクでないことが保証されます。 ただ、これを if (do_lstat(...) && S_ISDIR(...)) { dirtype = dir; } glob_helper(...); #1 if (dir) { glob_helper(dir); #2 } とすると、#1のglob_helperによってファイルシステムに変更が加わると、 #2でシンボリックリンクに変わっている可能性があるため、危険があります。 もちろん、ruby以外からファイルシステムに変更が加わる可能性はありますが、 時間は短いのでより安全だし、ruby単独なら完全に安全です。 こういったことは、rb_w32_opendirのように一度に読んでも回避できないはずです。 ////////////////////////////////////////////////////////////////////////////////// >結局、そういう元のディレクトリを変更するような場合にはPOSTORDER >を使うべし、ということになるのでは。その例では、(_WIN32以外では) >再帰する前にopendir()することでちょっとマシになるかも知れません。 私はRev1.94で、可読性、高速性、安全性で妥協しないような実装に苦労したので、 この問題について客観的に見れなくなっている気がします。 **/のチェックがタイムリーでなくても安全ならいいんですが、 危険はあるが、フラグ、それも安全性とは本質的な関係のないフラグで 回避すべきというのは、使い勝手が悪い気がします。 本当に安全性として問題ないのでしょうか?他の人の意見も聞きたいです。私はWin32な人間なので、 正直よくわかりません。 ////////////////////////////////////////////////////////////////////////////////// コードはシンプルにしておきたいので、できれば「不定」のままのほうがいいのですが、 多数のファイルにマッチする場合は、メモリを大量に消費するので、 「上からマッチ」「下からマッチ」があったほうがいいのかもしれません。 考えてみたんですが、デフォルトが「上からマッチ」だと、 実装によってデフォルトの方が遅くなる場合もあり、(**/を厳格にした場合など) 望ましくありません。 そこで、デフォルトは不定かつ最速(現在の実装では「下からマッチ」と同じ)で、 Dir::GLOB_HEAD のような指定があれば「上からマッチ」 Dir::GLOB_TAIL のような指定があれば「下からマッチ」にする方が望ましい気がします。 仮に「上からマッチ」や「下からマッチ」が遅いとしても、望んでその動作を選ぶのなら 問題ないでしょうし。