[ruby-list:45513] プログラムの添削お願いいたします。
From:
Akira Hayakawa <ruby@...>
Date:
2008-09-21 08:06:27 UTC
List:
ruby-list #45513
ファイルシステムを読み込んで、ノードに格納して返すというプログラムです。
読み込んだツリーをXMLに吐き出すクラスはすでに作成しましたが、今手元にありません。
そのクラスも後で添削お願いしようかと思っています。
Javaからやってきた。一生懸命Rubyっぽく書いてみたつもりです。
何やってるのか分からないところとか、クラスの名前が気持ち悪いとか、そういうところがありましたら教えてください。
あと、ここを直せばもっと早くなるよというところがありましたらそれも教えてもらいたいです。
自分のシステムのルートから読むと大体30秒かかりました。
テストケースは、自分のrubyディレクトリから下を読み込んで、ちゃんとsizeが足されているかを簡単にチェックするものです。
他にテストすべき事があったらこれも教えてもらいたいです。読み込みとか書き出しとかはテストを書くのが難しい気がします。
#---------------lib/file_system_reader.rb-----------------
require "find"
# this is a class to read File system
# and return node as FileNode class.
# the size of FileNode's property "user_object" are
# properly set to cover all the node under the designated node.
class FileSystemReader
# need hashmap to retain
# path :String => node :FileNode
def initialize
@map = Hash.new
end
# read file system
# return root of system as FileNode
def read_system(root_path)
Find.find(root_path) do |path|
if FileTest.exist?(path)
stat = File::Stat.new(path)
property = FileProperty.new(stat.size)
node = FileNode.new(property)
@map[path] = node
@map[File.dirname(path)].add(node) if path != root_path
end
end
root_node = @map[root_path]
certify(root_node) # certify the size of tree under the node
return root_node # return root node of DefaultMutableTreeNode
end
:private
# add size of nodes under the node of argument "root_node" recursively.
def certify(root_node)
# if the root is leaf, just certify the node.
if root_node.leaf?
root_node.user_object.certified = true
else # if not leaf
# then if the node is not certified
# drop down to its children recursively
# until it is certified.
if !root_node.user_object.certified?
total_size = 0
total_size += root_node.user_object.size # add the size of itself
root_node.children.each do |child|
certify(child) # child certified
total_size += child.user_object.size # add sizes of its children
end
# child all certified.
root_node.user_object.size = total_size
root_node.user_object.certified = true
end
end
end
end
# property
# which represent file node in a file system.
# value "certified"
# is a flag represents state that the property
# is set a size value that cover all the node sizes under the node.
class FileProperty
attr_writer :certified
attr_accessor :size
def initialize(size, *args)
@size = size
@certified = false
end
def certified?
return @certified
end
end
# node class
# represents file node.
# this node has a user object like DefaultMutableTreeNode.
# the motivation to write this class though there already
# is a alternative like DefaultMutableTreeNode is that
# it is too slow to traverse File system by jruby 1.1.4
# so we must write mutable node that works in CRuby.
class FileNode
attr_reader :user_object, :children
def initialize(user_object)
@user_object = user_object
@children = Array.new
end
def add(node)
@children << node
end
def leaf?
return @children.empty?
end
end
#-------------test/test_file_system_reader.rb------------------
require "test/unit"
require "lib/file_system_reader"
# require "java"
class TestFileSystemReader < Test::Unit::TestCase
def setup
end
# test if the size is added under a root node properly.
def test_size
reader = FileSystemReader.new
dir = "/home/akira/program/ruby"
node = reader.read_system(dir)
size = 0
node.children.each do |child|
size += child.user_object.size
end
size += File::Stat.new(dir).size
assert_equal(node.user_object.size, size)
end
end
--
Akira Hayakawa <ruby@i-mail.jp>