Module: ParallelAncestry

Extended by:
Module::Cluster, ParallelAncestry
Included in:
ParallelAncestry
Defined in:
lib/namespaces.rb,
lib/parallel_ancestry.rb

Defined Under Namespace

Modules: Inheritance, ModuleSubclassInheritance Classes: InstanceAncestryStruct

Instance Method Summary collapse

Instance Method Details

#ancestor(instance) { ... } ⇒ Object Also known as: parent

Return parent for instance that matches match_ancestor_block.

Examples:

::ParallelAncestry.ancestor( some_instance ) do |this_parent|
  if this_parent.matches_arbitrary_condition
    true
  else
    false
  end
end

Parameters:

  • instance (Object)

    Child instance.

Yields:

  • Block used to match parent. The parameter is the parent instance, the return value true or false, reflecting whether or not block matched ancestor.

Returns:

  • (Object)

    A reference to parent matching block condition.



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
# File 'lib/parallel_ancestry.rb', line 127

def ancestor( instance, & match_ancestor_block )
  
  ancestor_instance = nil
  
  parents = parents( instance )
  
  # If we don't have ancestors explicitly declared for this instance, and if it is not 
  # a ::Class or ::Module (both are ::Modules) then we have an instance of a class,
  # so we can use the instance's class
  if parents.empty? and instance != ::Class
    
    instance_class = instance.class
    if match_ancestor_block.call( instance_class )
      ancestor_instance = instance.class
    end
        
  else

    parents.each do |this_parent|
      # we need a way to go from multiple parents to the one that makes up this chain
      # we use the match_ancestor_block to determine this - it should return true/false
      if match_ancestor_block.call( this_parent )
        ancestor_instance = this_parent
        break
      end
    end

  end
  
  return ancestor_instance
  
end

#ancestor_chain(instance) { ... } ⇒ Array<Object>

Returns ancestor chain defined for provided object.

Examples:

::ParallelAncestry.ancestor( some_instance ) do |this_parent|
  if this_parent.matches_arbitrary_condition
    true
  else
    false
  end
end

Parameters:

  • instance (Object)

    Instance for which ancestors are being looked up.

Yields:

  • Block used to match parent. The parameter is the parent instance, the return value true or false, reflecting whether or not block matched ancestor.

Returns:

  • (Array<Object>)

    An array containing references to parents matching block condition.



179
180
181
182
183
184
185
186
187
188
189
# File 'lib/parallel_ancestry.rb', line 179

def ancestor_chain( instance, & match_ancestor_block )
  
  ancestor_chain = [ this_ancestor = instance ]

  while this_ancestor = ancestor( this_ancestor, & match_ancestor_block )
    ancestor_chain.push( this_ancestor )
  end
  
  return ancestor_chain
  
end

#children(instance) ⇒ Array<Object>

Return a list of children for provided object.

Parameters:

  • instance (Object)

    Object instance.

Returns:

  • (Array<Object>)

    An array containing references to children.



42
43
44
45
46
# File 'lib/parallel_ancestry.rb', line 42

def children( instance )
  
  return ancestor_struct( instance ).children ||= ::Array::Unique.new( self )

end

#has_children?(instance) ⇒ true, false

Return whether provided object has children.

Parameters:

  • instance (Object)

    Object instance.

Returns:

  • (true, false)

    true or false.



81
82
83
84
85
# File 'lib/parallel_ancestry.rb', line 81

def has_children?( instance )
  
  return ! children( instance ).empty?

end

#has_parents?(instance) ⇒ true, false

Return whether provided object has parents.

Parameters:

  • instance (Object)

    Object instance.

Returns:

  • (true, false)

    true or false.



68
69
70
71
72
# File 'lib/parallel_ancestry.rb', line 68

def has_parents?( instance )
  
  return ! parents( instance ).empty?

end

#highest_children(instance) { ... } ⇒ Array<Object>

Returns the highest parent in each parent tree matching block condition. For simple linear trees, this is simply the first parent, but more complex trees quickly diverge into multiple branches, each of which then requires a highest match.

Examples:

::ParallelAncestry.highest_parents( some_instance ) do |this_parent|
  if this_parent.matches_arbitrary_condition
    true
  else
    false
  end
end

Parameters:

  • instance (Object)

    Instance for which parents are being looked up.

Yields:

  • Block used to match parent. The parameter is the parent instance, the return value true or false, reflecting whether or not block matched ancestor.

Returns:

  • (Array<Object>)

    An array containing references to highest parent in each parent tree matching block condition.



259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
# File 'lib/parallel_ancestry.rb', line 259

def highest_children( instance, & match_ancestor_block )

  # the first super module available for each tree

  highest_children_array = [ ]

  children( instance ).each do |this_child|
    
    # if we match this parent we are done with this branch and can go to the next
    if match_ancestor_block.call( this_child )

      highest_children_array.push( this_child )

    # otherwise our branch expands and we have to finish it before the next parent
    elsif has_children?( this_child )

      children_for_branch = highest_children( this_child, & match_ancestor_block )

      highest_children_array.concat( children_for_branch )

    end
    
  end

  return highest_children_array
  
end

#lowest_parents(instance) { ... } ⇒ Array<Object>

Returns the lowest parent in each parent tree matching block condition. For simple linear trees, this is simply the first parent, but more complex trees quickly diverge into multiple branches, each of which then requires a lowest match.

Examples:

::ParallelAncestry.lowest_parents( some_instance ) do |this_parent|
  if this_parent.matches_arbitrary_condition
    true
  else
    false
  end
end

Parameters:

  • instance (Object)

    Instance for which parents are being looked up.

Yields:

  • Block used to match parent. The parameter is the parent instance, the return value true or false, reflecting whether or not block matched ancestor.

Returns:

  • (Array<Object>)

    An array containing references to lowest parent in each parent tree matching block condition.



211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
# File 'lib/parallel_ancestry.rb', line 211

def lowest_parents( instance, & match_ancestor_block )

  # the first super module available for each tree

  lowest_parents_array = [ ]

  parents( instance ).each do |this_parent|
    
    # if we match this parent we are done with this branch and can go to the next
    if match_ancestor_block.call( this_parent )

      lowest_parents_array.push( this_parent )

    # otherwise our branch expands and we have to finish it before the next parent
    elsif has_parents?( this_parent )

      parents_for_branch = lowest_parents( this_parent, & match_ancestor_block )

      lowest_parents_array.concat( parents_for_branch )

    end
    
  end

  return lowest_parents_array
  
end

#match_ancestor(instance, ancestor_match_block) { ... } ⇒ Object

Returns the first ancestor (determined by ancestor_match_block) for which match_block is true.

Examples:

ancestor_match_block = ::Proc.new do |this_parent|
  if this_parent.matches_arbitrary_condition
    true
  else
    false
  end
end
::ParallelAncestry.match_ancestor( some_instance, ancestor_match_block ) do |this_parent|
  if this_parent.matches_arbitrary_condition
    true
  else
    false
  end
end

Parameters:

  • instance (Object)

    Instance for which parents are being looked up.

  • ancestor_match_block (Proc)

    Proc used to match parent. The parameter is the parent instance, the return value true or false, reflecting whether or not block matched ancestor.

Yields:

  • Block used to match parent. The parameter is the parent instance, the return value true or false, reflecting whether or not block matched.

Returns:

  • (Object)


314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
# File 'lib/parallel_ancestry.rb', line 314

def match_ancestor( instance, ancestor_match_block, & match_block )

  matched_ancestor = nil
  
  this_ancestor = instance

  if has_parents?( this_ancestor )

    begin
      if match_block.call( this_ancestor )
        matched_ancestor = this_ancestor
        break
      end
      break if this_ancestor.equal?( ::Object )
    end while this_ancestor = ancestor( this_ancestor, & ancestor_match_block )

  elsif match_block.call( this_ancestor )

    matched_ancestor = this_ancestor
    
  else

    matched_ancestor = match_ancestor( this_ancestor.class, ancestor_match_block, & match_block )
    
  end

  return matched_ancestor
  
end

#parents(instance) ⇒ Array<Object>

Return a list of parents for provided object.

Parameters:

  • instance (Object)

    Object instance.

Returns:

  • (Array<Object>)

    An array containing references to immediate parents for any configuration.



55
56
57
58
59
# File 'lib/parallel_ancestry.rb', line 55

def parents( instance )
  
  return ancestor_struct( instance ).parents ||= ::Array::Unique.new( self )

end

#register_child_for_parent(child, parent) ⇒ Array<Object>

Register instance as child of another instance.

Parameters:

  • child (Object)

    Child instance.

  • parent (Object)

    Parent instance.

Returns:

  • (Array<Object>)

    An array containing references to children.



95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/parallel_ancestry.rb', line 95

def register_child_for_parent( child, parent )

  parents_of_child = parents( child )
  children_of_parent = children( parent )

  # child order shouldn't be relevant
  children_of_parent.push( child )
  
  # parent order determines who wins conflicts, so we keep youngest first
  parents_of_child.unshift( parent )

  return self

end