Class: Xcodeproj::Project::Object::AbstractObjectAttribute

Inherits:
Object
  • Object
show all
Defined in:
lib/xcodeproj/project/object_attributes.rb

Overview

TODO:

Add support for a list of required values so objects can be validated before serialization ?

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.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(type, name, owner) ⇒ AbstractObjectAttribute

Creates a new attribute with the given type and name.

Attributes are expected to be instantiated only by the Xcodeproj::Project::Object::AbstractObject DSL methods.

Parameters:

  • type (Symbol)

    the type of the attribute.

  • name (Symbol)

    the name of the attribute.

  • owner (Class)

    the class that owns the attribute.



42
43
44
45
46
# File 'lib/xcodeproj/project/object_attributes.rb', line 42

def initialize(type, name, owner)
  @type  = type
  @name  = name
  @owner = owner
end

Instance Attribute Details

#classesArray<Class>

Returns the list of the classes accepted by the attribute.

Returns:

  • (Array<Class>)

    the list of the classes accepted by the attribute.



61
62
63
# File 'lib/xcodeproj/project/object_attributes.rb', line 61

def classes
  @classes
end

#classes_by_key{Symbol, Array<Class>}

Returns the list of the classes accepted by each key for attributes which store a dictionary.

Returns:

  • ({Symbol, Array<Class>})

    the list of the classes accepted by each key for attributes which store a dictionary.



66
67
68
# File 'lib/xcodeproj/project/object_attributes.rb', line 66

def classes_by_key
  @classes_by_key
end

#default_valueString, ...

Returns the default value, if any, for simple attributes.

Returns:

  • (String, Array, Hash)

    the default value, if any, for simple attributes.



71
72
73
# File 'lib/xcodeproj/project/object_attributes.rb', line 71

def default_value
  @default_value
end

#nameSymbol (readonly)

Returns the name of the attribute.

Returns:

  • (Symbol)

    the name of the attribute.



22
23
24
# File 'lib/xcodeproj/project/object_attributes.rb', line 22

def name
  @name
end

#ownerClass

Returns the class that owns the attribute.

Returns:

  • (Class)

    the class that owns the attribute.



26
27
28
# File 'lib/xcodeproj/project/object_attributes.rb', line 26

def owner
  @owner
end

#typeSymbol (readonly)

Returns the type of the attribute. It can be ‘:simple`, `:to_one`, `:to_many`.

Returns:

  • (Symbol)

    the type of the attribute. It can be ‘:simple`, `:to_one`, `:to_many`.



18
19
20
# File 'lib/xcodeproj/project/object_attributes.rb', line 18

def type
  @type
end

Instance Method Details

#get_value(object) ⇒ String, ...

Convenience method that returns the value of this attribute for a

given object.

Parameters:

  • object (AbstractObject)

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

Returns:



82
83
84
# File 'lib/xcodeproj/project/object_attributes.rb', line 82

def get_value(object)
  object.send(name)
end

#inspectString

Returns A string suitable for debugging the object.

Returns:

  • (String)

    A string suitable for debugging the object.



178
179
180
181
182
183
184
185
186
# 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_nameString

Returns The name of the attribute in camel case.

Examples:

attribute.new(:simple, :project_root)
attribute.plist_name #=> projectRoot

Returns:

  • (String)

    The name of the attribute in camel case.



54
55
56
# File 'lib/xcodeproj/project/object_attributes.rb', line 54

def plist_name
  @plist_name ||= CaseConverter.convert_to_plist(name, :lower)
end

#set_default(object) ⇒ void

Note:

It is extremely important to duplicate the default values otherwise kittens cry!

This method returns an undefined value.

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.

Parameters:

  • object (AbstractObject)

    the object for which to set the default value.



119
120
121
122
123
124
# 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) ⇒ void

This method returns an undefined value.

Convenience method that sets the value of this attribute for a

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

Parameters:

  • object (AbstractObject)

    the object for which to set the value.

  • new_value (String, Hash, Array, AbstractObject)

    the value to set for the attribute.

Raises:

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



100
101
102
103
104
105
# 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) ⇒ void

This method returns an undefined value.

Checks that a given value is compatible with the attribute.

This method powers the runtime type checking of the Xcodeproj::Project::Object::AbstractObject and is used its by synthesised methods.

Raises:

  • If the class of the value is not compatible with the attribute.



135
136
137
138
139
140
141
142
143
144
145
# 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) ⇒ Object

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

This method is used by the #Xcodeproj::Project::ObjectDictionary class.

Raises:

  • If the class of the value is not compatible with the given key.



155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
# 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