Class: Hashery::IniHash

Inherits:
Object show all
Defined in:
lib/hashery/ini_hash.rb

Overview

Hash class with methods to read from and write into ini files.

A ini file is a text file in a specific format, it may include several fields which are sparated by field headlines which are enclosured by “[]”. Each field may include several key-value pairs.

Each key-value pair is represented by one line and the value is sparated from the key by a “=”.

Examples

Example ini file

# this is the first comment which will be saved in the comment attribute
[email protected]
domain=example.com # this is a comment which will not be saved
[database]
db=example
user=john
passwd=very-secure
host=localhost
# this is another comment
[filepaths]
tmp=/tmp/example
lib=/home/john/projects/example/lib
htdocs=/home/john/projects/example/htdocs
[ texts ]
wellcome=Wellcome on my new website!
Website description = This is only a example. # and another comment

Example object

Ini#comment stores:

"this is the first comment which will be saved in the comment attribute"

Ini’s internal hash stores:

{
 "mail" => "[email protected]",
 "domain" => "example.com",
 "database" => {
  "db" => "example",
  "user" => "john",
  "passwd" => "very-secure",
  "host" => "localhost"
 },
 "filepaths" => {
  "tmp" => "/tmp/example",
  "lib" => "/home/john/projects/example/lib",
  "htdocs" => "/home/john/projects/example/htdocs"
 }
 "texts" => {
  "wellcome" => "Wellcome on my new website!",
  "Website description" => "This is only a example."
 }
}

As you can see this module gets rid of all comments, linebreaks and unnecessary spaces at the beginning and the end of each field headline, key or value.

Using the object

Using the object is stright forward:

ini = IniHash.new("path/settings.ini")
ini["mail"] = "[email protected]"
ini["filepaths"] = { "tmp" => "/tmp/example" }
ini.comment = "This is\na comment"
puts ini["filepaths"]["tmp"]
# => /tmp/example
ini.write()

Acknowlegements

IniHash is based on ini.rb.

Copyright © 2007 Jeena Paradies <[email protected]>

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(path, load = nil) ⇒ IniHash

Creating a new IniHash object.

Parameters:

  • path

    is a path to the ini file

  • load (defaults to: nil)

    if nil restores the data if possible if true restores the data, if not possible raises an error if false does not resotre the data



114
115
116
117
118
119
120
121
# File 'lib/hashery/ini_hash.rb', line 114

def initialize(path, load=nil)
  @path    = path if String === path
  @inihash = (Hash === path ? path.dup : {})

  if load or ( load.nil? and FileTest.readable_real? @path )
    restore()
  end
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(s, *a, &b) ⇒ Object

TODO:

Sublcass Hash instead of delegating.

Delegate missing mthods to underlying Hash.



207
208
209
# File 'lib/hashery/ini_hash.rb', line 207

def method_missing(s,*a,&b)
  @inihash.send(s, *a, &b) if @inihash.respond_to?(s)
end

Instance Attribute Details

#commentObject

The string which holds the comments on the top of the file



104
105
106
# File 'lib/hashery/ini_hash.rb', line 104

def comment
  @comment
end

#inihashObject

The hash which holds all INI data.



99
100
101
# File 'lib/hashery/ini_hash.rb', line 99

def inihash
  @inihash
end

Class Method Details

.load(path, load = true) ⇒ Object

NOTE: In future versions, ‘#new` will not take a path, and `#load` will have to be used.



92
93
94
# File 'lib/hashery/ini_hash.rb', line 92

def self.load(path, load=true)
  new(path, load)
end

.read_comment_from_file(path) ⇒ Object

Reading comments from file

Parameters:

  • path

    a path to the INI file

Returns:

  • a ‘String` with the comments from the beginning of the INI file.



261
262
263
264
265
266
267
268
269
270
271
272
273
274
# File 'lib/hashery/ini_hash.rb', line 261

def self.read_comment_from_file(path)
  comment = ""
  
  IO.foreach(path) do |line|
    line.strip!

    break unless line[0,1] == "#" or line == ""

    comment_line = line[1, line.length].to_s
    comment << "#{comment_line.strip}\n"
  end
  
  comment
end

.read_from_file(path) ⇒ Object

Reading data from file

Parameters:

  • path

    a path to the ini file

Returns:

  • a ‘Hash` which represents the data from the file.



218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
# File 'lib/hashery/ini_hash.rb', line 218

def self.read_from_file(path)
  raise "file not found - #{path}" unless File.file?(path)

  inihash = {}
  headline = nil

  IO.foreach(path) do |line|
    line = line.strip.split(/#/)[0].to_s

    # read it only if the line doesn't begin with a "=" and is long enough
    unless line.length < 2 and line[0,1] == "="
      
      # it's a headline if the line begins with a "[" and ends with a "]"
      if line[0,1] == "[" and line[line.length - 1, line.length] == "]"

        # get rid of the [] and unnecessary spaces
        headline = line[1, line.length - 2 ].strip
        inihash[headline] = {}
      else
        key, value = line.split(/=/, 2)
        
        key = key.strip unless key.nil?
        value = value.strip unless value.nil?
        
        unless headline.nil?
          inihash[headline][key] = value
        else
          inihash[key] = value unless key.nil?
        end
      end        
    end
  end
  
  inihash
end

.text(inihash = {}) ⇒ Object Also known as: to_s

TODO:

Rename ‘IniHash.text` method to something else ?

Turn a hash (up to 2 levels deepness) into a ini string

Parameters:

  • inihash (defaults to: {})

    Hash representing the ini File. Default is a empty hash.

Returns:

  • a String in the ini file format.



310
311
312
# File 'lib/hashery/ini_hash.rb', line 310

def self.text(inihash={})
  new(inihash).to_s
end

.write_to_file(path, inihash = {}, comment = nil) ⇒ Object

Writing a ini hash into a file

Parameters:

  • path

    Path to the INI file.

  • inihash (defaults to: {})

    Hash representing the ini File. Default is a empty hash.

  • comment (defaults to: nil)

    String with comments which appear on the top of the file. Each line will get a “#” before. Default is no comment.

Raises:

  • (TypeError)


285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
# File 'lib/hashery/ini_hash.rb', line 285

def self.write_to_file(path, inihash={}, comment=nil)
  raise TypeError, "String expected" unless comment.is_a? String or comment.nil?
  
  raise TypeError, "Hash expected" unless inihash.is_a? Hash
  File.open(path, "w") { |file|
    
    unless comment.nil?
      comment.each do |line|
        file << "# #{line}"
      end
    end

    file << IniHash.text(inihash)
  }
end

Instance Method Details

#[](key) ⇒ Object

Retrive the ini data for the key key



126
127
128
# File 'lib/hashery/ini_hash.rb', line 126

def [](key)
  @inihash[key]
end

#[]=(key, value) ⇒ Object

Set the ini data for the key key

Parameters:

  • key

    Index key.

  • value

    The value to index.

Returns:

  • value.



138
139
140
141
142
143
144
145
146
# File 'lib/hashery/ini_hash.rb', line 138

def []=(key, value)
  #raise TypeError, "String expected" unless key.is_a? String
  key = key.to_str
 
  #raise TypeError, "String or Hash expected" unless value.is_a? String or value.is_a? Hash
  value = value.to_str unless Hash === value

  @inihash[key] = value
end

#inspectObject



178
# File 'lib/hashery/ini_hash.rb', line 178

alias :inspect :to_s

#restoreObject

Restores the data from file into the object



151
152
153
154
# File 'lib/hashery/ini_hash.rb', line 151

def restore
  @inihash = IniHash.read_from_file(@path)
  @comment = IniHash.read_comment_from_file(@path)
end

#saveObject

Store data from the object in the file.



159
160
161
# File 'lib/hashery/ini_hash.rb', line 159

def save
  IniHash.write_to_file(@path, @inihash, @comment)
end

#to_hObject

Convert to hash by duplicating the underlying hash table.



174
175
176
# File 'lib/hashery/ini_hash.rb', line 174

def to_h
  @inihash.dup
end

#to_sObject

Turn a hash (up to 2 levels deepness) into a ini string

Parameters:

  • inihash

    Hash representing the ini File. Default is a empty hash.

Returns:

  • a string in the ini file format.



187
188
189
190
191
192
193
194
195
196
197
198
199
200
# File 'lib/hashery/ini_hash.rb', line 187

def to_s
  str = ""
  inihash.each do |key, value|
    if value.is_a? Hash
      str << "[#{key.to_s}]\n"
      value.each do |under_key, under_value|
        str << "#{under_key.to_s}=#{under_value.to_s unless under_value.nil?}\n"
      end
    else
      str << "#{key.to_s}=#{value.to_s unless value.nil?}\n"
    end
  end
  str
end

#updateObject

Deprecated.

Do not use this in new code, and replace it when updating old code.

Save INI data to file path. Use #save instead.



166
167
168
169
# File 'lib/hashery/ini_hash.rb', line 166

def update
  warn 'IniHash#update is deprecated for this use, use IniHash#save instead.'
  save
end