IniFile再び
まえに、iniFileを読むためのRubyのクラスを実装したのを書いたけれど、ちょっと直しました。以前のものは、指定した、セクション、キーが存在しない場合、""を返すようにしていたのですが、Rubyっぽく、nilを返すようにしました。 iniH = IniFile.new( fileSpec)でファイルから読み、 hash = iniH[ section名 ] でセクション全体をハッシュで返します。セクションがない場合、nilが返ります。セクションの有無を確認の上、キーにアクセスするには、 raise "NO section" if ! iniH[ セクション名 ] value = iniH[セクション名][キー名]のようにします。新たにセクション、キーを指定して値を追加する場合には、 (iniH[ セクション名] || iniH[ セクション名] = Hash.new)[key名] = 値みたいになります。ほとんどパズルみたいなので、[], []=を定義しなおしてみました。これで、 val = iniH[ セクション名, キー名] と書くことができます。目的とするセクションや、キーがない場合はnilが返ります。 また、 iniH[ セクション名、 キー名 ] = valueという、書き方ができます。この場合、指定したセクションが存在しない場合は、新たにセクションを追加し、キーにvalueを関連付けます。それよりも嵌ったのは、正規表現で、キーと値の抽出は、/(.*)=(.*)/ではなく、/(.*?)=(.*)/,つまり最短一致にしておかないとちょっと動作がまずそうです。## (c)2009 BO# inifile# class IniFile < Hash @@ReComment = /^#/ @@ReSection =/\[(.*)\]/ @@ReKeyValue =/(.*?)=(.*)/ def initialize( fileSpec = nil ) if fileSpec File::open( fileSpec) {|f| sectionName = "" while line = f.gets if line =~ @@ReComment # skip a line elsif line =~ @@ReSection sectionName = $1.strip elsif line =~ @@ReKeyValue self[ sectionName, $1.strip] = $2.strip if sectionName != "" end end # while } end end #def initialize( fileSpec = nil ) def write2File( fileSpec ) fp = File.open( fileSpec ,'w') fp.print to_s() fp.close end #def write2File( filespec ) def to_s str = String.new self.each_key{ |section| str += "[#{section}]\n" if self[section] self[section].each_key{|key| str += "#{key}=#{self[section][key]}\n" if self[section][key] } end } str end #def to_s def []( section, *rest) return super(section) if rest.length == 0 key=rest[0] self[section] ? self[section][key] : nil end # def []( section, *rest) def []=( section, *rest ) if rest.length == 1 hash = rest[0] return super( section, hash) elsif rest.length == 2 key, val = rest[0], rest[1] return (self[section] || super(section, Hash.new))[ key ]= val else raise "invalid number of param" end end #def []=( section, *rest )end # class IniFile