Sha256: 96739c74015a8f452b3ae5444e3e8709ecff171fac44d3a4bfc3e69369714767

Contents?: true

Size: 1.94 KB

Versions: 2

Compression:

Stored size: 1.94 KB

Contents

module Machinist

  # When you make an object, the blueprint for that object is instance-evaled
  # against a Lathe.
  #
  # The Lathe implements all the methods that are available to the blueprint,
  # including method_missing to let the blueprint define attributes.
  class Lathe

    def initialize(klass, serial_number, attributes = {})
      @klass               = klass
      @serial_number       = serial_number
      @assigned_attributes = {}

      @object              = @klass.new
      attributes.each {|key, value| assign_attribute(key, value) }
    end

    # Returns a unique serial number for the object under construction.
    def sn
      @serial_number
    end

    # Returns the object under construction.
    attr_reader :object

    def method_missing(attribute, *args, &block) #:nodoc:
      unless attribute_assigned?(attribute)
        assign_attribute(attribute, make_attribute(attribute, args, &block))
      end
    end

    # Undef a couple of methods that are common ActiveRecord attributes.
    # (Both of these are deprecated in Ruby 1.8 anyway.)
    undef_method :id   if respond_to?(:id)
    undef_method :type if respond_to?(:type)

  protected

    def make_attribute(attribute, args, &block) #:nodoc:
      count = args.shift if args.first.is_a?(Fixnum)
      if count
        Array.new(count) { make_one_value(attribute, args, &block) }
      else
        make_one_value(attribute, args, &block)
      end
    end

    def make_one_value(attribute, args) #:nodoc:
      raise_argument_error(attribute) unless args.empty?
      yield
    end
    
    def assign_attribute(key, value) #:nodoc:
      @assigned_attributes[key.to_sym] = value
      @object.send("#{key}=", value)
    end
  
    def attribute_assigned?(key) #:nodoc:
      @assigned_attributes.has_key?(key.to_sym)
    end

    def raise_argument_error(attribute) #:nodoc:
      raise ArgumentError.new("Invalid arguments to attribute #{attribute} in blueprint") 
    end

  end
end

Version data entries

2 entries across 2 versions & 2 rubygems

Version Path
machinist-2.0 lib/machinist/lathe.rb
indirect-machinist-2.0.0.beta3 lib/machinist/lathe.rb