module Bogo::Lazy::ClassMethods

Class methods for laziness

Public Instance Methods

always_clean!() click to toggle source

Disable dirty state

# File lib/bogo/lazy.rb, line 117
def always_clean!
  self.class_eval do
    def dirty?(*args); false; end
    def valid_state; self; end
    alias_method :dirty, :data
    alias_method :attributes, :data
  end
end
attribute(name, type, options={}) click to toggle source

Add new attributes to class

@param name [String] @param type [Class, Array<Class>] @param options [Hash] @option options [TrueClass, FalseClass] :required must be provided on initialization @option options [Object, Proc] :default default value @option options [Proc] :coerce @return [nil]

# File lib/bogo/lazy.rb, line 135
def attribute(name, type, options={})
  name = name.to_sym
  options = options.to_smash
  attributes[name] = Smash.new(:type => type).merge(options)
  coerce = attributes[name][:coerce]
  valid_types = [attributes[name][:type], NilClass].flatten.compact
  allowed_values = attributes[name][:allowed]
  multiple_values = attributes[name][:multiple]
  depends_on = attributes[name][:depends]
  define_method(name) do
    send(depends_on) if depends_on
    self.class.on_missing(self) unless data.has_key?(name) || dirty.has_key?(name)
    if(dirty.has_key?(name))
      dirty[name]
    else
      if(data.has_key?(name))
        val = data[name]
      else
        val = self.class.attributes[name][:default]
      end
      if(val.respond_to?(:dup))
        begin
          val = val.dup
        rescue
          val
        end
      end
      if(val.respond_to?(:freeze))
        val.freeze
      else
        val
      end
    end
  end
  define_method("#{name}=") do |val|
    values = multiple_values && val.is_a?(Array) ? val : [val]
    values.map! do |item|
      valid_type = valid_types.detect do |klass|
        item.is_a?(klass)
      end
      if(coerce && !valid_type)
        item = coerce.arity == 2 ? coerce.call(item, self) : coerce.call(item)
        if(item.is_a?(Hash) && item[:bogo_multiple])
          item = item[:bogo_multiple]
        else
          item = [item]
        end
      else
        item = [item]
      end
      invalid_type = item.detect do |_item|
        valid_types.none? do |klass|
          _item.is_a?(klass)
        end
      end
      if(invalid_type)
        raise TypeError.new("Invalid type for `#{name}` (#{invalid_type} <#{invalid_type.class}>). Valid - #{valid_types.map(&:to_s).join(',')}")
      end
      if(allowed_values)
        unallowed = item.detect do |_item|
          !allowed_values.include?(_item)
        end
        if(unallowed)
          raise ArgumentError.new("Invalid value provided for `#{name}` (#{unallowed.inspect}). Allowed - #{allowed_values.map(&:inspect).join(', ')}")
        end
      end
      item
    end
    values.flatten!(1)
    if(!multiple_values && !val.is_a?(Array))
      dirty[name] = values.first
    else
      dirty[name] = values
    end
  end
  define_method("#{name}?") do
    send(depends_on) if depends_on
    self.class.on_missing(self) unless data.has_key?(name)
    !!data[name]
  end
  nil
end
attributes(*args) click to toggle source

Return attributes

@param args [Symbol] :required or :optional @return [Array<Hash>]

# File lib/bogo/lazy.rb, line 222
def attributes(*args)
  @attributes ||= Smash.new
  if(args.include?(:required))
    Smash[@attributes.find_all{|k,v| v[:required]}]
  elsif(args.include?(:optional))
    Smash[@attributes.find_all{|k,v| !v[:required]}]
  else
    @attributes
  end
end
dirty?(*args) click to toggle source
# File lib/bogo/lazy.rb, line 119
def dirty?(*args); false; end
on_missing(param=nil) click to toggle source

Instance method to call on missing attribute or object to call method on if set

@param param [Symbol, Object] @return [Symbol]

# File lib/bogo/lazy.rb, line 238
def on_missing(param=nil)
  if(param)
    if(param.is_a?(Symbol))
      @missing_method = param
    else
      if(@missing_method && !@calling_on_missing)
        @calling_on_missing = true
        begin
          param.send(@missing_method)
        ensure
          @calling_on_missing = false
        end
      end
      @missing_method
    end
  else
    @missing_method
  end
end
set_attributes(attrs) click to toggle source

Directly set attribute hash

@param attrs [Hash] @return [TrueClass] @todo need deep dup here

# File lib/bogo/lazy.rb, line 263
def set_attributes(attrs)
  @attributes = attrs.to_smash
  true
end
valid_state() click to toggle source
# File lib/bogo/lazy.rb, line 120
def valid_state; self; end