class Kitchen::LazyHash

A modifed Hash object that may contain callables as a value which must be executed in the context of another object. This allows for delayed evaluation of a hash value while still looking and largely feeling like a normal Ruby Hash.

@example normal hash accessing with regular values

data = {
  :symbol => true,
  "string" => "stuff"
}
context = "any object"
lazy = Kitchen::Hash.new(data, context)

lazy[:symbol] # => true
lazy.fetch("string") # => "stuff"

@example hash with callable blocks as values

data = {
  :lambda => ->(c) { c.length },
  :proc => Proc.new { |c| c.reverse },
  :simple => "value"
}
context = "any object"
lazy = Kitchen::Hash.new(data, context)

lazy[:lambda] # => 10
lazy.fetch(:proc) # => "tcejbo yna"
lazy[:simple] # => "value"

@author Fletcher Nichol <fnichol@nichol.ca>

Public Class Methods

new(obj, context) click to toggle source

Creates a new LazyHash using a Hash-like object to populate itself and an object that can be used as context in value-callable blocks. The context object can be used to compute values for keys at the time of fetching the value.

@param obj [Hash, Object] a hash-like object @param context [Object] an object that can be used to compute values

Calls superclass method
# File lib/kitchen/lazy_hash.rb, line 63
def initialize(obj, context)
  @context = context
  super(obj)
end

Public Instance Methods

[](key) click to toggle source

Retrieves the rendered value object corresponding to the key object. If not found, returns the default value.

@param key [Object] hash key @return [Object, nil] the value for key or the default value if key is

not found
# File lib/kitchen/lazy_hash.rb, line 74
def [](key)
  proc_or_val(__getobj__[key])
end
delete_if(&block) click to toggle source

Returns a new Hash after deleting the key-value pairs for which the block returns true.

@return [Hash] a new hash

# File lib/kitchen/lazy_hash.rb, line 130
def delete_if(&block)
  to_hash.delete_if(&block)
end
each(&block) click to toggle source

If no block provided, returns an enumerator over the keys and rendered values in the underlying object. If a block is provided, calls the block once for each [key, rendered_value] pair in the underlying object.

@return [Enumerator, Array]

# File lib/kitchen/lazy_hash.rb, line 122
def each(&block)
  to_hash.each(&block)
end
fetch(key, default = :__undefined__, &block) click to toggle source

Returns a rendered value from the hash for the given key. If the key can't be found, there are several options: With no other arguments, it will raise an KeyError exception; if default is given, then that will be returned; if the optional code block is specified, then that will be run and its result returned.

@param key [Object] hash key @param default [Object] default value if key is not set (optional) @return [Object, nil] the value for the key or the default value if key

is not found

@raise [KeyError] if the key is not found

# File lib/kitchen/lazy_hash.rb, line 89
def fetch(key, default = :__undefined__, &block)
  case default
  when :__undefined__
    proc_or_val(__getobj__.fetch(key, &block))
  else
    proc_or_val(__getobj__.fetch(key, default, &block))
  end
end
select(&block) click to toggle source

Yields each key/value pair to the provided block. Returns a new Hash with only the keys and rendered values for which the block returns true.

@return [Hash] a new hash

# File lib/kitchen/lazy_hash.rb, line 112
def select(&block)
  to_hash.select(&block)
end
to_hash() click to toggle source

Returns a new Hash with all keys and rendered values of the LazyHash.

@return [Hash] a new hash

# File lib/kitchen/lazy_hash.rb, line 101
def to_hash
  hash = {}
  __getobj__.each_key { |key| hash[key] = self[key] }
  hash
end

Private Instance Methods

proc_or_val(thing) click to toggle source

Returns an object or invokes call with context if object is callable.

@return [Object] an object @api private

# File lib/kitchen/lazy_hash.rb, line 140
def proc_or_val(thing)
  if thing.respond_to?(:call)
    thing.call(@context)
  else
    thing
  end
end