Context is a list of mirrors applicable within current method call
stack. It contains mirrors of all Elements which are on method call
stack.
General Context
Context levels form chains:
Shadows
- history of mirrors applied to original ElementPure. When Element is
returned to upper Context, it can be Context where its ElementPure
original reference was mirrored (possibly subsequently). Then its
ElementPure counterpart is resolved back to former reference.
Length of following Shadows chain is independent from length of Context
chain. That's because:
only some of the Context
nodes in current Context chain have
mirrors applicable to given reference
in one ElementPure.original
mutation chain there can be several
ElementPure nodes, and their mirrors apply to given reference
even one ElementPure
mutation generation can have several mirrors which apply in cascade to
one object
Shadows.called
nodes are a subset of Context.called
nodes which had at least one mirror applicable to given
reference.
Here mutated sweet_Jane,
dear_Jack, mum_Laura, daughter_Jane and
student_Jack
are accessible only in Context of their "owners"
Mr_Jack, Ms_Jane (2x)
and Mrs_Laura (2x)
respectively.
That's because whenever these mutated objects are returned from within
their "owners"
by getXyzExternal(),
they are resolved
back to their originals.
Talking on the same page:
Mr_Jack.printGirlfriend()
==> "sweet Jane"
Mr_Jack.returnGirlfriend()
==> Ms_Jane
Mr_Jack.girlfriend
is sweet_Jane
with
history of being Ms_Jane outside
Context of Mr_Jack
sweet_Jane
is returned
sweet_Jane
is converted to caller's
Context,
and because of its history it is resolved back to Ms_Jane
Mrs_Laura.returnDaughter()
==> Ms_Jane
Mrs_Laura.daughter
evaluates to daughter_Jane with
history of being Ms_Jane
outside Context of Mrs_Laura
daughter_Jane
is returned
daughter_Jane
is converted to caller's
Context,
and because of its history it is resolved back to Ms_Jane
Mrs_Laura.daughter
field, although within context of Mrs_Laura,
is evaluated to sweet_Jane with
history of being Ms_Jane
outside Context of Mr_Jack.
That's because Mr_Jack's
mirror [Ms_Jane
==> sweet_Jane]
has priority to Mrs_Laura's
mirror [Ms_Jane
==> daughter_Jane]
This way references to
same objects are consistent in various
Contexts. References to Ms_Jane
get mirrored to sweet_Jane
while within Context of Mr_Jack.
It applies to both Elements passed there
from upper Context, or retrieved from reference field.
Mrs_Laura.returnDaughter()
returns sweet_Jane
from Context of Mrs_Laura
(within Context of Mr_Jack)
upwards to Context of Mr_Jack.
It's not resolved back to Ms_Jane,
because it still remains within Context of Mr_Jack,
where it
was mirrored to sweet_Jane.
Mrs_Laura.daughter
within context of Mr_Jack
evaluates to sweet_Jane
with history of being Ms_Jane
outside Context of Mr_Jack
Mrs_Laura.getDaughter()
returns sweet_Jane
Mr_Jack
returns sweet_Jane
sweet_Jane
is converted to caller's
Context, and
because of its history it is resolved back to Ms_Jane
These examples show how references are returned from within a Context
where they are mirrored. They are resolved to originals from which they
were mirrored in actual Context. That's necessary for consistent
structural relations in any Context.
@TODO example with a relation
in upper Context, mirror in lower Context
Element comparison
There are special situations where inner representation is to be used
outside its Context - in methods such as equals(),
compareTo(), hashCode(), toString().
Linked chains
- LIFO use - Shadows
linked upside-down trees - used as maps, e.g. ElementPure's/Context's
mirrors
cascades lists with shared
nodes - i.e. trees used upside down