Sha256: 5524cab93327a774da770fa5764ae54fdc44b537ad67016504b1b36fa68e49aa

Contents?: true

Size: 1.83 KB

Versions: 16

Compression:

Stored size: 1.83 KB

Contents

#
# +MethodedHash+
#
# is a subclass of Hash which basically will create an accessor method
# for every key in the hash, transforming all sub-hashes into +MethodedHash+
# classes and so on (recursive).
#
# Please note: it will *NOT* add a method if the method already exist.
#
class MethodedHash < Hash

  def initialize(h = {})
    duplicate_hash(h)
    self
  end

  def []=(key, value)
    super
    common_methodizer(key)
  end

private

  def duplicate_hash(arg)
    arg.each do
      |k, v|
      self[k] = arg[k].dup
      #
      # we want to replicate MethodedHashes all along but we cannot use the
      # self.class.new(...) construct because it may create a subclass and
      # the result might not be what we want. So we define a protected class
      # method that will force-create a MethodedHash class (and that can be
      # overridden when needed)
      #
      self[k] = self.class.create(v) if v.kind_of?(Hash)
    end
  end

  def common_methodizer(k)
    methodize(k)
  end

  #
  # +methodize(key)+
  #
  # this is the method that normalizes keys (to be able to transform them in
  # methods. Please note that "methodization" will only happen if the
  # class does not already respond to a normalized key method.
  #
  def methodize(key)
    nk = normalize_key(key)
    iname = ('@' + nk.to_s).to_sym
    self.instance_variable_set(iname, self[key])
    define_singleton_method(nk) { self.instance_variable_get(iname) } unless self.respond_to?(nk)
  end

  def normalize_key(key)
    ek = key.to_s.gsub(/\W/, '_')
    ek.to_sym
  end

protected

  class << self

    #
    # +create(h = {})+
    #
    # +create+ force-creates a MethodedHash class, avoiding potential
    # conflicts with children classes. However it can be overridden by
    # children classes if needed.
    #
    def create(h = {})
      MethodedHash.new(h)
    end

  end

end

Version data entries

16 entries across 16 versions & 1 rubygems

Version Path
ruby-mext-0.21.6 lib/ruby/extensions/methoded_hash.rb
ruby-mext-0.21.5 lib/ruby/extensions/methoded_hash.rb
ruby-mext-0.21.4 lib/ruby/extensions/methoded_hash.rb
ruby-mext-0.21.3 lib/ruby/extensions/methoded_hash.rb
ruby-mext-0.21.2 lib/ruby/extensions/methoded_hash.rb
ruby-mext-0.21.1 lib/ruby/extensions/methoded_hash.rb
ruby-mext-0.21.0 lib/ruby/extensions/methoded_hash.rb
ruby-mext-0.20.1 lib/ruby/extensions/methoded_hash.rb
ruby-mext-0.20.0 lib/ruby/extensions/methoded_hash.rb
ruby-mext-0.19.0 lib/ruby/extensions/methoded_hash.rb
ruby-mext-0.18.3 lib/ruby/extensions/methoded_hash.rb
ruby-mext-0.18.2 lib/ruby/extensions/methoded_hash.rb
ruby-mext-0.18.1 lib/ruby/extensions/methoded_hash.rb
ruby-mext-0.18.0 lib/ruby/extensions/methoded_hash.rb
ruby-mext-0.17.0 lib/ruby/extensions/methoded_hash.rb
ruby-mext-0.16.2 lib/ruby/extensions/methoded_hash.rb