Class: Hashery::CRUDHash

Inherits:
Hash show all
Defined in:
lib/hashery/crud_hash.rb

Overview

The CRUDHash is essentailly the same as the Hash class, but it reduces the the set of necessary methods to the fundametal CRUD requirements. All other methods route through these CRUD methods. This is a better general design, although it is, of course, a little bit slower. The utility of this class becomes appearent when subclassing or delegating, as only a handful of methods need to be changed for all other methods to work accordingly.

In addition to the CRUD features, CRUDHash supports a ‘#key_proc`, akin to `#default_proc`, that can be used to normalize keys.

The CRUD methods are:

  • key?

  • fetch

  • store

  • delete

In addition to these main methods, there are these supporting “CRUD” methods:

  • default

  • default_proc

  • default_proc=

  • key_proc

  • key_proc=

Constant Summary collapse

NA =

Dummy object for null arguments.

Object.new

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Hash

create, #rekey, #rekey!, #to_stash

Class Method Details

.[](*hash) ⇒ Object

This method is overridden to ensure that new entries pass through the ‘#store` method.

Parameters:

  • hash (#each)

    Single Hash, associative array or just a list of pairs.



43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/hashery/crud_hash.rb', line 43

def self.[](*hash)
  h = new
  if hash.size == 1
    hash.first.each do |k,v|
      h.store(k, v) 
    end       
  else
    hash.each do |(k,v)|
      h.store(k, v) 
    end
  end
  h
end

.auto(*args, &block) ⇒ Object

Alternate to #new which auto-creates sub-dictionaries as needed. By default the ‘default_proc` procuced a empty Hash and is self-referential so every such Hash also has the same `default_proc`.

Examples:

d = CRUDHash.auto
d["a"]["b"]["c"] = "abc"  #=> { "a"=>{"b"=>{"c"=>"abc"}}}

Parameters:

  • args

    Pass-thru arguments to ‘#new`.

  • block

    Alternate internal procedure for default proc.

Returns:

  • ‘Hash`.



72
73
74
75
76
77
78
79
# File 'lib/hashery/crud_hash.rb', line 72

def self.auto(*args, &block)
  if block
    leet = lambda { |hsh, key| hsh[key] = block.call(hsh, key) }
  else
    leet = lambda { |hsh, key| hsh[key] = new(&leet) }
  end
  new(*args, &leet)
end

Instance Method Details

#<<(assoc) ⇒ Object

Update Hash with assoc.

Parameters:

  • assoc

    Two-element ‘Array` or a `Hash`.

Returns:

  • assoc.



214
215
216
217
218
219
220
221
222
223
224
225
# File 'lib/hashery/crud_hash.rb', line 214

def <<(assoc)
  case assoc
  when Hash
    update(assoc)
  when Array
    assoc.each_slice(2) do |(k,v)|
      store(k,v)
    end
  else
    raise ArgumentError  # or TypeError ?
  end
end

#[](key) ⇒ Object

Operator for ‘#retrieve`.

Parameters:

  • key

    Index key to lookup.

Returns:

  • ‘Object` value of key.



234
235
236
# File 'lib/hashery/crud_hash.rb', line 234

def [](key)
  retrieve(key)
end

#[]=(key, value) ⇒ Object

Operator for ‘#store`.

Parameters:

  • key

    The ‘Object` to act as indexing key.

  • value

    The ‘Object` to associate with key.

Returns:

  • value.



246
247
248
# File 'lib/hashery/crud_hash.rb', line 246

def []=(key,value)
  store(key,value)
end

#cast(hash) ⇒ Object (private)

Cast a given ‘hash` in accordance to the `#key_proc`.

Parameters:

  • hash

    Any object the responds to ‘#each` like a Hash.

Returns:

  • ‘Hash`.



368
369
370
371
372
373
374
# File 'lib/hashery/crud_hash.rb', line 368

def cast(hash)
  h = {}
  hash.each do |k,v|
    h[cast_key(k)] = v
  end
  h
end

#cast_key(key) ⇒ Object (private)

Callback for normalizing hash keys.

Parameters:

  • key

    Index key.

Returns:

  • key after passing through the ‘key_proc`.



383
384
385
# File 'lib/hashery/crud_hash.rb', line 383

def cast_key(key)
  @key_proc ? @key_proc.call(key) : key
end

#default_proc(&block) ⇒ Object

Allow ‘#default_proc` to take a block.

Parameters:

  • block

    The ‘Proc` object to set the `default_proc`.

Returns:

  • ‘Proc`, the `default_proc`.



118
119
120
121
# File 'lib/hashery/crud_hash.rb', line 118

def default_proc(&block)
  self.default_proc = block if block
  super()
end

#delete(key) ⇒ Object

CRUD method for delete.

Parameters:

  • key

    Hash key to remove.

Returns:

  • value of deleted Hash entry.



169
170
171
# File 'lib/hashery/crud_hash.rb', line 169

def delete(key)
  super cast_key(key)
end

#eachObject Also known as: each_pair

Iterate over each hash pair.



286
287
288
289
290
291
292
293
294
# File 'lib/hashery/crud_hash.rb', line 286

def each #:yield:
  if block_given?
    keys.each do |k|
      yield(k, retrieve(k))
    end
  else
    to_enum(:each)
  end
end

#fetch(key, *default) ⇒ Object

CRUD method for read. This method gets the value for a given key. An error is raised if the key is not present, but an optional argument can be provided to be returned instead.

Parameters:

  • key

    Hash key to lookup.

  • default

    Value to return if key is not present.

Returns:

  • the ‘Object` that is the Hash entry’s value.

Raises:

  • KeyError when key is not found and default has not been given.



146
147
148
# File 'lib/hashery/crud_hash.rb', line 146

def fetch(key, *default)
   super(cast_key(key), *default)
end

#key?(key) ⇒ Boolean Also known as: has_key?, member?, include?

CRUD method for checking if key exists.

Parameters:

  • key

    Hash key to lookup.

Returns:

  • (Boolean)

    ‘true/false`.



130
131
132
# File 'lib/hashery/crud_hash.rb', line 130

def key?(key)
  super cast_key(key)
end

#key_proc(&block) ⇒ Object

Get/set ‘key_proc`.

Examples:

ch = CRUDHash.new
ch.key_proc

Returns:

  • ‘Proc`.



106
107
108
109
# File 'lib/hashery/crud_hash.rb', line 106

def key_proc(&block)
  @key_proc = block if block
  @key_proc
end

#key_proc=(proc) ⇒ Object

Set ‘key_proc`.

Examples:

ch = CRUDHash.new
ch.key_proc = Proc.new{ |key| key.to_sym }

Returns:

  • ‘Proc`.

Raises:

  • (ArgumentError)


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

def key_proc=(proc)
  raise ArgumentError unless Proc === proc or NilClass === proc
  @key_proc = proc
end

#merge(other) ⇒ Object

Merge the Hash with another hash, returning a new Hash.

Parameters:

  • other

    Other hash or hash-like object to add to the hash.

Returns:

  • ‘Hash`.



276
277
278
279
280
281
# File 'lib/hashery/crud_hash.rb', line 276

def merge(other)
  #super(other.rekey{ |key| cast_key(key) })
  copy = dup
  other.each{ |k,v| copy.store(k, v) }
  copy
end

#read(key) ⇒ Object

Method for reading value. Returns ‘nil` if key is not present.

Note that this method used to be the CRUD method instead of #retrieve. Complaints about #read being indicative of an IO object (though in my opinion that is a bad asumption) have led to this method’s deprecation.

Parameters:

  • key

    Hash key to lookup.

Returns:

  • value of Hash entry.



202
203
204
205
# File 'lib/hashery/crud_hash.rb', line 202

def read(key)
  warn "The #read method as been deprecated. Use #retrieve instead."
  retrieve(key)
end

#replace(other) ⇒ Object

Replace current entries with those from another Hash, or Hash-like object. Each entry is run through the casting procedure as it is added.

Parameters:

  • other

    Hash-like object.

Returns:

  • self.



325
326
327
# File 'lib/hashery/crud_hash.rb', line 325

def replace(other)
   super cast(other)
end

#retrieve(key) ⇒ Object

Like #fetch but returns the results of calling ‘default_proc`, if defined, otherwise `default`.

Parameters:

  • key

    Hash key to lookup.

Returns:

  • value of Hash entry or ‘nil`.



183
184
185
186
187
188
189
# File 'lib/hashery/crud_hash.rb', line 183

def retrieve(key)
  if key?(key)
    fetch(key)
  else
    default_proc ? default_proc.call(self, key) : default
  end
end

#store(key, value) ⇒ Object

CRUD method for create and update.

Parameters:

  • key

    The ‘Object` to act as indexing key.

  • value

    The ‘Object` to associate with key.

Returns:

  • value.



158
159
160
# File 'lib/hashery/crud_hash.rb', line 158

def store(key, value)
  super(cast_key(key), value)
end

#to_hashObject Also known as: to_h

TODO:

Since a CRUDHash is a subclass of Hash should #to_hash just ‘#dup`

insted of converting to traditional Hash?

Convert CRUDHash to regular Hash.



345
346
347
# File 'lib/hashery/crud_hash.rb', line 345

def to_hash
  h = {}; each{ |k,v| h[k] = v }; h
end

#update(other) ⇒ Object Also known as: merge!

Update the Hash with another hash.

Parameters:

  • other

    Other hash or hash-like object to add to the hash.

Returns:

  • self.



257
258
259
260
261
262
# File 'lib/hashery/crud_hash.rb', line 257

def update(other)
  other.each do |k,v|
    store(k, v)
  end
  self
end

#values_at(*keys) ⇒ Object

Get the values at.

Parameters:

  • keys

    List of keys to lookup.

Returns:

  • ‘Array` of values.



336
337
338
# File 'lib/hashery/crud_hash.rb', line 336

def values_at(*keys)
  super *keys.map{ |key| cast_key(key) }
end