Class: Hashery::OpenCascade

Inherits:
OpenHash show all
Defined in:
lib/hashery/open_cascade.rb

Overview

OpenCascade is subclass of OpenHash. It differs in a few significant ways. The reason this class is called “cascade” is that every internal Hash is transformed into an OpenCascade dynamically upon access. This makes it easy to create “cascading” references.

h = { :x => { :y => { :z => 1 } } }
c = OpenCascade[h]
c.x.y.z  #=> 1

As soon as you access a node it automatically becomes an OpenCascade.

c = OpenCascade.new   #=> #<OpenCascade:0x7fac3680ccf0 {}>
c.r                   #=> #<OpenCascade:0x7fac368084c0 {}>
c.a.b                 #=> #<OpenCascade:0x7fac3680a4f0 {}>

But if you set a node, then that will be that value.

c.a.b = 4             #=> 4

To query a node without causing the auto-creation of an OpenCasade instance, use the ‘?`-mark.

c.a.z?                #=> nil

OpenCascade also transforms Hashes within Arrays.

h = { :x=>[ {:a=>1}, {:a=>2} ], :y=>1 }
c = OpenCascade[h]
c.x.first.a.assert == 1
c.x.last.a.assert  == 2

Finally, you can set call a private method via bang methods using the ‘!`-mark.

c = OpenCascade.new   #=> #<OpenCascade:0x7fac3680ccf0 {}>
c.each = 4
c.each! do |k,v|
  ...
end

c.x!(4).y!(3)         #=> #<OpenCascade:0x7fac3680ccf0 {:x=>4, :y=>3}>

Subclassing OpenCascade with cause the new subclass to become the class that is auto-created. If this is not the behavior desired, consider using delegation instead of subclassing.

Constant Summary

Constants inherited from CRUDHash

CRUDHash::NA

Instance Attribute Summary

Attributes inherited from OpenHash

#safe

Instance Method Summary collapse

Methods inherited from OpenHash

#close!, #open!, #open?, #store

Methods inherited from CRUDHash

#<<, #[], [], #[]=, auto, #cast, #cast_key, #default_proc, #delete, #each, #fetch, #key?, #key_proc, #key_proc=, #merge, #read, #replace, #store, #to_hash, #update, #values_at

Methods inherited from Hash

create, #rekey, #rekey!, #to_hash, #to_stash

Constructor Details

#initialize(*default) ⇒ OpenCascade

Initialize new OpenCascade instance.



64
65
66
67
68
69
# File 'lib/hashery/open_cascade.rb', line 64

def initialize(*default)
  @read = {}

  leet = lambda { |h,k| h[k] = self.class.new(&leet) }
  super(*default, &leet)
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(sym, *args, &blk) ⇒ Object



95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/hashery/open_cascade.rb', line 95

def method_missing(sym, *args, &blk)
  type = sym.to_s[-1,1]
  name = sym.to_s.gsub(/[=!?]$/, '').to_sym

  case type
  when '='
    store(name, args.first)
  when '?'
    key?(name) ? retrieve!(name) : nil    # key?(name)
  when '!'
    __send__(name, *args, &blk)
  else
    #if key?(name)
      retrieve(name)
    #else
    #  #default = OpenCascade.new #self.class.new
    #  #default = default_proc ? default_proc.call(self, name) : default
    #  store(name, read(name))
    #end
  end
end

Instance Method Details

#cast_value(entry) ⇒ Object (private)

Cast value, such that Hashes are converted to OpenCascades. And Hashes in Arrays are converted to OpenCascades as well.



133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/hashery/open_cascade.rb', line 133

def cast_value(entry)
  case entry
  when Hash
    e = OpenCascade.new
    e.key_proc = key_proc if key_proc
    e.merge!(entry)
    e
  when Array
    entry.map{ |e| cast_value(e) }
  else
    entry
  end
end

#respond_to?(sym, include_private = false) ⇒ Boolean



117
118
119
# File 'lib/hashery/open_cascade.rb', line 117

def respond_to?(sym, include_private = false)
  sym != :to_ary && super
end

#retrieve(key) ⇒ Object

Read value given a key.



83
84
85
86
87
88
89
90
# File 'lib/hashery/open_cascade.rb', line 83

def retrieve(key)
  ckey = cast_key(key)
  if @read[ckey]
    super(key)
  else
    @read[ckey] = store(key, cast_value(super(key)))
  end
end

#retrieve!Object

Alias for original read method.



74
# File 'lib/hashery/open_cascade.rb', line 74

alias :retrieve! :retrieve