From: Minero Aoki Date: 2001-12-21T10:08:15+09:00 Subject: [ruby-dev:15513] Re: fileutils (2) あおきです。 In mail "[ruby-dev:15512] Re: fileutils (2)" TAKAHASHI Masayoshi wrote: > 高橋征義です。 > > すみません、つっこみを入れてしまいます。しかも長いです。 いえいえ、いくらでもどうぞ。 > あ、互換性はいったん捨てることにしたんですね。 > では、改めて考えてみましょう。 まあ、互換性というか「どうせ 1.7 以降に入るんだから 1.7 以降 対応でいいじゃん」または「いまさら 1.6 なんて使えるかぁっ!」 ということです。それに、あくまで 1.7 用なのはテストスクリプトで、 本体は 1.6 でも動きますから。ついでに ftools と上位互換でも あるはずです (File に extend するとそのまま通用する)。 > * オプションがいろいろある > fileutilsの最新版ではこれをどう解決しているかというと、 > > FileUtils#cd( [options,] dir ) > > というように、オプションを最初の引数に持ってきてます。ここで > cd(:verbose, :noop, some_dir) とかという感じで指定するわけ > ですね。 > このため、dirが何番目の引数になるかは決まってはいない > ようになっています。……うーん、これはちょっとRuby的には > 不自然な気が。 でも、メソッド名から言っても cp なら cp(1) のように働いてほしいと 思うのではないでしょうか? (本当は話が逆だけど) この場合に限っては Ruby 的であるよりもシェル的であるほうがよいのではないかと思うのです。 あるいは、オプションを前じゃなくて後ろに与えた場合 dir の位置は 固定になりますけどそれはどうでしょう? 実装としては、オプションは どこでもいい、というのも可能です。 > なんでこうなっているかというと、 > > FileUtils#ln_s( [options,] file1, file2 ..., dir ) > > というように、任意の数の引数を取るメソッドがあるのと、 > Unixのコマンドがオプションを前に持ってくる習慣があるから > だろうと思います(あってます?)。 はい。そのとおりです。 > なお、このようなことをするための実装の方はといえば、 > > def newest?( *args ) > (new,*fnames), (verbose,) = fu_parseargs( args, 1..INF, :verbose ) > > というように、引数は配列で受けて、fu_parseargsでparseしてから、 > 多重代入で受ける、という感じになっているようです。ちなみにこのINFは、 > > INF = 1/0.0 > > という定義になってますね。うむむむ。 ちょっとトリッキーですかね。 > ところで、上のln_sのように、file1,file2,...とたくさん並べる > 必要はあるのでしょうか? shell上でその都度コマンドを入力する > ならいざしらず、Rubyのスクリプトならメソッドを並べるなり、 > eachで回すなりすればいいような。 たとえば rb = %w( mail.rb loader.rb field.rb .... ) rb2 = %w( parsemail.rb ) としておいて cp rb, rb2, mkdir_p(site_ruby + '/tmail') ってのがとっても楽なんですよー。each でまわすとするとこれは (rb + rb2).flatten.each do |fname| cp fname, mkdir_p(site_ruby + '/tmail') end となって面倒です。 また本当にコピーだけでいいなら copy_file(a,b) というメソッドも あります。同様なものに remove_file(n) remove_dir(n) も。 > というわけで、発想を少し(かなり)転換させて、cpやln_sやmkdirと > いった一連のメソッドは、FileUtilsモジュールのモジュール関数 > ではなく、FileUtilsクラスのインスタンスメソッドにする、と > いうのはどうでしょうか。 そういうことなら include FileUtils::Verbose で全部 verbose になります。クラスに include してインスタンス化 しても使えます。あ、private だからだめなのか。それなら public に しましょう。 また、インスタンス化できるようにすること自体は特に問題ないですけど、 include する方法もやはり欲しいです。やっぱ cp ならいきなり cp と 書きたいので。(あくまで個人的欲求として、です) > こうすると、 > fu.verbose = true > fu.noop = true このタイプは前に話が出たときにどなたかから否定的な意見が出たので 避けました。たとえば preserve を例にとると、cp や cp_r はいいけど mv や ln を呼んだとき preserve アトリビュートにどういう意味がある のかよくわからないというのが理由です。 あとそのときは、たけさんから op = FileUtils.operator(:cp, :preserve) op.exec みたいな感じに cp するためのインスタンスを作るのはどうか? という 意見もありました。(メソッド名その他は変えてます) ------------------------------------------------------------------- 青木峰郎