From: nobu.nakada@... Date: 2001-08-23T11:47:42+09:00 Subject: [ruby-list:31085] Re: File#join なかだです。 At Wed, 22 Aug 2001 23:21:23 +0900, K.Umakoshi wrote: > File#join とか File#split とか使った事ないんですが… > ファイル名を扱うクラスがあればいいなと思って、 > ruby の勉強を兼ねてこんなクラスを作ってます。  こういうのがあれば別のプラットフォーム用のパス名を扱うことが できるかも知れません。とりあえず私も作ってみたので添付します。 > class FileName < String > PF_UNIX = 0  Socket::PF_UNIXと紛らわしくないでしょうか。それにこうやって場 合分けをするよりも、Unix用、Windows用、DOS用のクラスにしたいよ うな気も。 > PLATFORM = PF_DOS > Separator = '\\' > Separators = Separator  DOSでもシステムコールレベルでは'/'も有効だったと思います。そ れにFile::SEPARATOR, File::ALT_SEPARATORという定数が既に用意さ れているので、そっちを使ったほうが面倒が少なそうです。もしくは 上記のようにプラットフォーム別のクラスにするなら、それぞれの定 数にするか。 > def <=>(name) > case PLATFORM > when PF_WINDOWS || PF_DOS  これだとPF_DOSにはマッチしません。 when PF_WINDOWS, PF_DOS > def clean > clean(self) > end  再帰しようとしてArgumentErrorになりそうです。 type.clean(self) > [3 TestFileName.rb ] (snip) > s1 = FileName.new('a') > s2 = FileName.new('A') > assert(s1.icasecmp(s2) == 0)  すいません、これって正しいんでしょうか。 class File class Name < String def self.clean(path) return "" if path.empty? paths = path.split(self::Separators) paths[0] ||= "" clean_paths = Array.new paths.each do |elm| case elm when '.' # abandon when '..' case clean_paths.last when nil, '..' clean_paths.push(elm) when '' # abandon else clean_paths.pop end else clean_paths.push(elm) end end if clean_paths.empty? clean_paths.push(".") elsif clean_paths.last.empty? clean_paths.push("") end clean_paths.join(self::Separator) end def self.split(path) if i = path.rindex(self::Separators) return path[0, i.nonzero? || 1], path[i.next..-1] else return ".", path end end def self.join(path, *paths) paths.each do |elem| m = elem.rindex(self::Separators, 0) if path.index(self::Separators, -1) elem = m.post_match if m else path << self::Separator unless m end path << elem end path end def clean type.clean(self) end def <=>(name) clean <=> type.clean(name) end def ==(name) (self <=> name).zero? end class Unix < Name Separator = '/' Separators = /\/+/ end class DOS < Name Separator = '\\' Separators = /[\\\/:]+/ Drive = /\A[a-z]:/i def self.clean(path) if m = Drive.match(path) m[0]+super(m.post_match) else super end end def self.split(path) if m = Drive.match(path) dir, base = super(m.post_match) return m[0]+dir, base else super end end def <=>(name) clean.upcase <=> type.clean(name).upcase end end class Windows < DOS UNC = /\A[\\\/]{2}/ def self.clean(path) if UNC === path self::Separator+super else super end end end Default = case RUBY_PLATFORM when /cygwin|mswin32|mingw/ Windows when /djgpp/ DOS else Unix end end def self.Name(path = nil) name = Name::Default name = name.new(path) if path name end end -- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦