[ruby-list:316] Reqest for Find and BUG report
From:
keiju@... (Keiju ISHITSUKA)
Date:
1996-07-19 07:57:06 UTC
List:
ruby-list #316
けいじゅ@SHLジャパンです.
Findモジュールという便利なものがあるというので, 調べていたのですが, プ
ログラムがなっていません. もっと良いものに修正して下さい.
以下が オリジナルのソースです.
# Usage:
# require "find.rb"
#
# Find.find('/foo','/bar') {|f| ...}
# or
# include Find
# find('/foo','/bar') {|f| ...}
#
module Find
extend Find
def findpath(path, ary)
ary.push(path)
[1] d = Dir.open(path)
for f in d
next if f =~ /^\.\.?$/
f = path + "/" + f
if File.directory? f
findpath(f, ary)
else
ary.push(f)
end
end
end
private :findpath
def find(*path)
ary = []
for p in path
findpath(p, ary)
for f in ary
yield f
end
end
end
module_function :find
end
理由1:
[1]でオープンしたディレクトリがクローズしていない. ちゃんとクローズ
して下さい. このままだとディレクトリをファイルオープンのlimit分だけ
開くと動かなくなります.
あと, このままのアルゴリズムでファイルをクローズするようにしても, ディ
レクトリの深さがlimit分までしか実行できません. 同時に複数のディレク
トリをオープンしないで済むようなものに変えて下さい.
理由2:
findpath で, 全部のファイルの配列を作ってから ここのファイルに対して,
ブロックを評価していますが, これはちょっとひどいと思います. ファイル
を1つ見つけたらその場でブロックを評価するようにして下さい.
というわけで, 以下のような定義はいかがでしょう?
module Find
extend Find
def find(*path)
ary = path.clone
while not (file = ary.shift).nil?
yield file
if File.directory? file and not File.symlink? file then
d = Dir.open(file)
for f in d
next if f =~ /^\.\.?$/
if file == "/" then
f = "/" + f
else
f = file + "/" + f
end
ary.push f
end
d.close
end
end
end
module_function :find
end
ここで, バグレポート:
Findを実行すると, ディレクトリがシンポリックリンクの時もその中にはいっ
てしまって無限ループにはいってしまうことがあります. それを避けるために:
File.symlink? file
で判断するようにしたのですが, どうもバグっているようです. 調べて下さい.
あと,
test ?s, file
もおかしいようです(1024が帰ります).
今度は質問: コマンドのfindでは, ツリーの探索を途中で辞めたりできるよう
になっていますよね. それをruby版Findで実現することは可能なのでしょうか?
例えば,
Find.find(dir){|file| if cond then File.prune end}
などのようにですね.
上記のプログラムですと yield file を行なった時に, その外側の while を
nextできれば良いのですが... それは無理ですよね(?_?
__
.........................................石塚 圭樹@SHLジャパン(株)...
------------>アドレス変わりました!! e-mail: keiju@shljapan.co.jp <----