Class: Hashery::OpenHash

Inherits:
CRUDHash show all
Defined in:
lib/hashery/open_hash.rb

Overview

OpenHash is a Hash, but also supports open properties much like OpenStruct.

Only names that are name methods of Hash can be used as open slots. To open a slot for a name that would otherwise be a method, the method needs to be made private. The `#open!` method can be used to handle this.

o = OpenHash.new
o.open!(:send)
o.send = 4

Direct Known Subclasses

OpenCascade

Instance Method Summary (collapse)

Methods inherited from CRUDHash

#<<, #[], #[]=, #delete, #each, #fetch, #key?, #key_proc, #key_proc=, #merge, #replace, #store, #to_hash, #update, #values_at

Methods inherited from Hash

#to_keyhash, #to_stash

Methods included from CoreExt

#rekey, #rekey!, #to_h, #to_hash

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

- (Object) method_missing(s, *a, &b)



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/hashery/open_hash.rb', line 54

def method_missing(s,*a, &b)
  type = s.to_s[-1,1]
  name = s.to_s.sub(/[!?=]$/, '')
  key  = name.to_sym

  case type
  when '='
    #open!(key) unless open?(key)
    self[key] = a.first
  when '!'
    # call an underlying private method
    # TODO: limit this to omitted methods (from included) ?
    __send__(name, *a, &b)
  when '?'
    key?(key)
  else
    if key?(key)
      self[key]
    else
      super(s,*a,&b)
    end
  end
end

Instance Method Details

- (Object) close!(*methods)

Make specific Hash methods available for use that have previously opened.



49
50
51
# File 'lib/hashery/open_hash.rb', line 49

def close!(*methods)
  (class << self; self; end).class_eval{ public *methods }
end

- (Object) open!(*methods) Also known as: omit!

Open up a slot that that would normally be a Hash method.

The only methods that can't be opened are ones starting with `__`.



31
32
33
34
# File 'lib/hashery/open_hash.rb', line 31

def open!(*methods)
  methods.reject!{ |x| x.to_s =~ /^__/ }
  (class << self; self; end).class_eval{ private *methods }
end

- (Boolean) open?(method)

Is a slot open?

Returns:

  • (Boolean)


42
43
44
# File 'lib/hashery/open_hash.rb', line 42

def open?(method)
  ! public_methods(true).include?(method.to_sym)
end