class Xcodeproj::Project::Object::AbstractObjectAttribute

This class represents an attribute of {AbstractObject} subclasses. Attributes are created by the {AbstractObject} DSL methods and allow to mirror the underlying attributes of the xcodeproj document model.

Attributes provide support for runtime type checking. They also allow {AbstractObject} initialization and serialization to plist.

@todo Add support for a list of required values so objects can be

validated before serialization ?

Attributes

classes[RW]

@return [Array<Class>] the list of the classes accepted by the

attribute.
classes_by_key[RW]

@return [{Symbol, Array<Class>}] the list of the classes accepted by

each key for attributes which store a dictionary.
default_value[RW]

@return [String, Array, Hash] the default value, if any, for simple

attributes.
name[R]

@return [Symbol] the name of the attribute.

owner[RW]

@return [Class] the class that owns the attribute.

type[R]

@return [Symbol] the type of the attribute. It can be ‘:simple`,

`:to_one`, `:to_many`.

Public Class Methods

new(type, name, owner) click to toggle source

Creates a new attribute with the given type and name.

Attributes are expected to be instantiated only by the {AbstractObject} DSL methods.

@param [Symbol] type

the type of the attribute.

@param [Symbol] name

the name of the attribute.

@param [Class] owner

the class that owns the attribute.
# File lib/xcodeproj/project/object_attributes.rb, line 42
def initialize(type, name, owner)
  @type  = type
  @name  = name
  @owner = owner
end

Public Instance Methods

get_value(object) click to toggle source

Convenience method that returns the value of this attribute for a

given object.

@param [AbstractObject] object

the object for which the value of this attribute is requested.

@return [String, Array, Hash, AbstractObject, ObjectList]

the value.
# File lib/xcodeproj/project/object_attributes.rb, line 82
def get_value(object)
  object.send(name)
end
inspect() click to toggle source

@return [String] A string suitable for debugging the object.

# File lib/xcodeproj/project/object_attributes.rb, line 178
def inspect
  if type == :simple
    "Attribute `#{plist_name}` (type: `#{type}`, classes: " \
      "`#{classes}`, owner class: `#{owner.isa}`)"
  else
    "Attribute `#{plist_name}` (type: `#{type}`, classes: " \
      "`#{classes.map(&:isa)}`, owner class: `#{owner.isa}`)"
  end
end
plist_name() click to toggle source

@return [String] The name of the attribute in camel case.

@example

attribute.new(:simple, :project_root)
attribute.plist_name #=> projectRoot
# File lib/xcodeproj/project/object_attributes.rb, line 54
def plist_name
  @plist_name ||= CaseConverter.convert_to_plist(name, :lower)
end
set_default(object) click to toggle source

Convenience method that sets the value of this attribute for a given object to the default (if any). It makes sense only for ‘:simple` attributes.

@param [AbstractObject] object

the object for which to set the default value.

@note It is extremely important to duplicate the default values

otherwise kittens cry!

@return [void]

# File lib/xcodeproj/project/object_attributes.rb, line 119
def set_default(object)
  unless type == :simple
    raise "[Xcodeproj] Set value called for a #{type} attribute"
  end
  set_value(object, default_value.dup) if default_value
end
set_value(object, new_value) click to toggle source

Convenience method that sets the value of this attribute for a

given object. It makes sense only for `:simple` or `:to_one`
attributes.

@raise It the type of this attribute is ‘:to_many`.

@param [AbstractObject] object

the object for which to set the value.

@param [String, Hash, Array, AbstractObject] new_value

the value to set for the attribute.

@return [void]

# File lib/xcodeproj/project/object_attributes.rb, line 100
def set_value(object, new_value)
  if type == :to_many
    raise '[Xcodeproj] Set value called for a to-many attribute'
  end
  object.send("#{name}=", new_value)
end
validate_value(object) click to toggle source

Checks that a given value is compatible with the attribute.

This method powers the runtime type checking of the {AbstractObject} and is used its by synthesised methods.

@raise If the class of the value is not compatible with the attribute.

@return [void]

# File lib/xcodeproj/project/object_attributes.rb, line 135
def validate_value(object)
  return unless object
  acceptable = classes.find { |klass| object.class == klass || object.class < klass }
  if type == :simple
    raise "[Xcodeproj] Type checking error: got `#{object.class}` " \
      "for attribute: #{inspect}" unless acceptable
  else
    raise "[Xcodeproj] Type checking error: got `#{object.isa}` for " \
      "attribute: #{inspect} - #{object.uuid} #{object.to_ascii_plist}" unless acceptable
  end
end
validate_value_for_key(object, key) click to toggle source

Checks that a given value is compatible with a key for attributes which store references by key.

This method is used by the #{ObjectDictionary} class.

@raise If the class of the value is not compatible with the given

key.
# File lib/xcodeproj/project/object_attributes.rb, line 155
def validate_value_for_key(object, key)
  unless type == :references_by_keys
    raise '[Xcodeproj] This method should be called only for ' \
      'attributes of type `references_by_keys`'
  end

  unless classes_by_key.keys.include?(key)
    raise "[Xcodeproj] unsupported key `#{key}` " \
      "(accepted `#{classes_by_key.keys}`) for attribute `#{inspect}`"
  end

  return unless object
  classes = Array(classes_by_key[key])
  acceptable = classes.find { |klass| object.class == klass || object.class < klass }
  unless acceptable
    raise "[Xcodeproj] Type checking error: got `#{object.isa}` " \
      "for key `#{key}` (which accepts `#{classes}`) of " \
      "attribute: `#{inspect}`"
  end
end