Class: Isomorphic::Factory::AbstractFactory Abstract

Inherits:
Object
  • Object
show all
Defined in:
lib/isomorphic/factory.rb

Overview

This class is abstract.

Subclass and override #const_get and #xmlattrs to implement a custom class.

Generic base class for Isomorphic factories.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(base) ⇒ AbstractFactory

Default constructor

Parameters:

  • the base module



43
44
45
46
47
# File 'lib/isomorphic/factory.rb', line 43

def initialize(base)
  super()

  @base = base
end

Instance Attribute Details

#baseObject (readonly)

Returns the value of attribute base.



38
39
40
# File 'lib/isomorphic/factory.rb', line 38

def base
  @base
end

Instance Method Details

#for(klass, **options) {|instance| ... } ⇒ Object

Build a new instance of the given class.

Parameters:

  • the class

  • the options

Options Hash (**options):

  • :attributes (Hash<#to_sym, Object>) — default: {}

    the attributes for the new instance

  • :xmlattrs (Hash<#to_sym, #to_s>) — default: {}

    the XML attributes for the new instance

Yield Parameters:

  • instance (Object)

    the new instance

Yield Returns:

  • (void)

Returns:

  • the new instance

Raises:

  • if the given class cannot be found



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/isomorphic/factory.rb', line 59

def for(klass, **options, &block)
  unless klass.is_a?(::Class) && (klass.parents[-2] == base)
    raise Isomorphic::InvalidFactoryClass.new(nil, base, klass, nil)
  end

  instance = klass.new

  if options.key?(:attributes)
    update_attributes(instance, options[:attributes])
  end

  send(:xmlattrs).select { |xmlattr_name|
    instance.respond_to?(:"xmlattr_#{xmlattr_name}=")
  }.each do |xmlattr_name|
    instance.send(:"xmlattr_#{xmlattr_name}=", send(:"xmlattr_#{xmlattr_name}_for", instance))
  end

  unless block.nil?
    case block.arity
      when 1 then block.call(instance)
      else instance.instance_eval(&block)
    end
  end

  instance
end

#path(instance, *method_names, **options) ⇒ Object?

Build a chain of new instances by reflecting on the instance methods for the given instance and then return the end of the chain.

Parameters:

  • the instance

  • the method names

  • the options

Options Hash (**options):

  • :try (Boolean) — default: false

    return nil if any receiver in the chain is blank

  • :attributes (Hash<#to_sym, Object>) — default: {}

    the attributes for the new instance

  • :xmlattrs (Hash<#to_sym, #to_s>) — default: {}

    the XML attributes for the new instance

Returns:

  • the new instance or nil

Raises:

  • if any class in the chain cannot be found



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/isomorphic/factory.rb', line 97

def path(instance, *method_names, **options)
  method_names.inject([instance.class, instance]) { |pair, method_name|
    orig_class, orig_instance = *pair

    if orig_instance.nil? && options[:try]
      [::NilClass, orig_instance]
    else
      s = method_name.to_s
      const_name = s[0].upcase.concat(s[1..-1])

      new_class = const_get(base, orig_class, const_name)

      unless new_class.is_a?(::Class)
        raise Isomorphic::InvalidFactoryClass.new(nil, base, orig_class, const_name)
      end

      new_instance = orig_instance.send(method_name) || (options[:try] ? nil : orig_instance.send(:"#{method_name}=", send(:for, new_class)))

      [new_class, new_instance]
    end
  }[1]
end

#path?(instance, *method_names) ⇒ Boolean

Is the chain of instances present?

Parameters:

  • the instance

  • the method names

Returns:

  • true if the chain of instances is present; otherwise, false

Raises:

  • if any class in the chain cannot be found



126
127
128
# File 'lib/isomorphic/factory.rb', line 126

def path?(instance, *method_names)
  !path(instance, *method_names, try: true).nil?
end

#update_attributes(instance, attributes = {}) ⇒ void

Note:

Before assignment, attributes from the passed-in hash are duplicated.

This method returns an undefined value.

Updates the attributes of the instance from the passed-in hash.

Parameters:

  • the instance

  • (defaults to: {})

    the attributes



137
138
139
140
141
142
143
# File 'lib/isomorphic/factory.rb', line 137

def update_attributes(instance, attributes = {})
  attributes.each do |method_name, value|
    instance.send(:"#{method_name}=", ::Marshal.load(::Marshal.dump(value)))
  end

  return
end

#xmlattrsArray<#to_sym>

Note:

For each XML attribute name, e.g., name, a corresponding instance method #xmlattr_{name}_for(instance) must be defined.

Returns the array of XML attribute names that are accepted by this factory.

Returns:

  • the XML attribute names



150
151
152
# File 'lib/isomorphic/factory.rb', line 150

def xmlattrs
  []
end