Module: Bogo::Lazy::ClassMethods

Defined in:
lib/bogo/lazy.rb

Overview

Class methods for laziness

Instance Method Summary collapse

Instance Method Details

#always_clean!Object

Disable dirty state



107
108
109
110
111
112
113
114
# File 'lib/bogo/lazy.rb', line 107

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 = {}) ⇒ nil

Add new attributes to class

Parameters:

  • name (String)
  • type (Class, Array<Class>)
  • options (Hash) (defaults to: {})

Options Hash (options):

  • :required (TrueClass, FalseClass)

    must be provided on initialization

  • :default (Object, Proc)

    default value

  • :coerce (Proc)

Returns:

  • (nil)


125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
# File 'lib/bogo/lazy.rb', line 125

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) ⇒ Array<Hash>

Return attributes

Parameters:

  • args (Symbol)

    :required or :optional

Returns:



212
213
214
215
216
217
218
219
220
221
# File 'lib/bogo/lazy.rb', line 212

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

#on_missing(param = nil) ⇒ Symbol

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

Parameters:

  • param (Symbol, Object) (defaults to: nil)

Returns:

  • (Symbol)


228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
# File 'lib/bogo/lazy.rb', line 228

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) ⇒ TrueClass

TODO:

need deep dup here

Directly set attribute hash

Parameters:

Returns:

  • (TrueClass)


253
254
255
256
# File 'lib/bogo/lazy.rb', line 253

def set_attributes(attrs)
  @attributes = attrs.to_smash
  true
end