擬似lsの実装
Posted feedbacks - Ruby
Rubyで.真面目にディレクトリツリーを作って処理しています.
ついでに,パスリストへの動的な追加(add)と,基準パス以下の仮想ファイル一覧の出力(lslR)を追加しました.
x = PathList.new("aaa/bbb", "aaa/ccc", "aaa/ddd/eee", "bbb/ddd/eee")
pp x.ls('aaa/')
=> ["bbb", "ccc", "ddd/"]
pp x.ls('aaa/ddd/')
=> ["eee"]
x.add('bbb/foo', 'bbb/bar', 'bbb/baz/hoge')
pp x.ls('bbb')
=> ["ddd/", "baz/", "foo", "bar"]
pp x.ls()
=> ["aaa/", "bbb/"]
pp x.lslR
=> ["aaa/bbb",
"aaa/ccc",
"aaa/ddd/eee",
"bbb/ddd/eee",
"bbb/baz/hoge",
"bbb/foo",
"bbb/bar"]
pp x.lslR('bbb')
=> ["bbb/ddd/eee", "bbb/baz/hoge", "bbb/foo", "bbb/bar"]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | class PathList
def initialize(*obj)
@files = Hash.new {|hash, key| hash[key] = PseudoDir.new(key) }
self.add(*obj) unless obj.empty?
end
def add(*obj)
obj.flatten.each do |path|
path = path2list(path)
@files[path[0]] += path[1..-1]
end
return self
end
def ls(path = '')
path = path2list(path)
return lscurdir if path.empty?
return @files[path[0]].ls(path[1..-1])
end
def lslR(path = '')
path = path2list(path)
return @files[path[0]].lslR(path[1..-1]) unless path.empty?
return self.traversal('')
end
def lscurdir
@files.map {|name, file| file.name }
end
def traversal(prefix = '')
@files.map do |name, file|
file.traversal(prefix + self.name)
end.flatten
end
def path2list(path)
return path unless path.class == String # XXX
path.split(%r|/|)
end
def name
''
end
end
class PseudoDir < PathList
def initialize(name = nil)
@name = name
super()
end
def +(obj)
name, rest = obj[0], obj[1..-1]
return PseudoFile.new(@name) if obj.empty?
@files[name] += rest
return self
end
def name
@name + '/'
end
end
class PseudoFile < PathList
attr_reader(:name)
def initialize(name)
@name = name
end
def +(obj)
raise "#{self.name}: PseudoFile already exists"
end
def ls(list = [])
return [] unless list.empty? # No such file or directory
return [self.name]
end
def traversal(prefix)
return prefix + self.name
end
end
__END__
|
正規表現です。grep に直接ブロックをわたし、Regexp.last_match をつかってみました。
1 2 3 4 5 6 7 8 9 10 | def ls(pl, q)
pl.grep(/^#{Regexp.quote(q)}\/?/) {|x|
x.sub(Regexp.last_match[0], "").sub(/\/.+/, "/")
}.delete_if {|i| i.empty? }
end
pathList = ["aaa/bbb","aaa/ccc","aaa/ddd/eee","bbb/ddd/eee"]
p ls(pathList, "aaa/") == ["bbb", "ccc", "ddd/"]
p ls(pathList, "aaa/ddd/") == ["eee"]
p ls(pathList, "aaa/ddd") == ["eee"]
|


ところてん
#4212()
Rating1/3=0.33
[ reply ]