From: Akira Hayakawa Date: 2008-09-21T17:06:27+09:00 Subject: [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