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