edu.vub.at.objects.mirrors
Class NATIntrospectiveMirror

java.lang.Object
  extended byedu.vub.at.objects.natives.NATNil
      extended byedu.vub.at.objects.natives.NATByRef
          extended byedu.vub.at.objects.mirrors.NATIntrospectiveMirror
All Implemented Interfaces:
ATAbstractGrammar, ATConversions, ATExpression, ATMirror, ATNil, ATObject, ATStatement, java.io.Serializable

public class NATIntrospectiveMirror
extends NATByRef
implements ATMirror

NATIntrospectiveMirror is a default mirror to represent an ambienttalk object which is capable of offering the java meta-interface of any language value at the ambienttalk level. This allows introspection into the language value's internals as well as invoking some meta-level operations on it. Technically, NATMirror is simply a wrapper object around an ambienttalk object which deifies (ups) methods invoked upon it.

Note that whereas the mirror can offer e.g. an apply method when reifying a closure, this does not affect its own meta-interface. A NATMirror is always an object and can thus not be applied at the ambienttalk level.

Example:
 def clo := { | x | x * 2 };
 def  m  := at.mirrors.Factory.createMirror(clo);
 
 clo( 5 )      => 10 (legal) 
 m.apply([5])  => 10 (legal) 
 m( 5 )        => error (Application expected a closure, given a mirror) 
 

Author:
smostinc, tvcutsem
See Also:
Serialized Form

Field Summary
private  ATObject principal_
          the object reflected on.
 
Fields inherited from class edu.vub.at.objects.natives.NATNil
_INSTANCE_
 
Constructor Summary
private NATIntrospectiveMirror(ATObject representation)
          An introspective mirror is a wrapper which forwards a deified (upped) version of invoked methods and field accesses to its principal.
 
Method Summary
static ATMirror atValue(ATObject objectRepresentation)
          Return a mirror on the given native or custom AmbientTalk object.
 ATMirror base_asMirror()
           
 ATObject base_getBase()
          Provides access to the AmbientTalk language value this mirror reflects upon.
 boolean base_isMirror()
           
 ATNil meta_assignField(ATObject receiver, ATSymbol name, ATObject value)
          The effect of assigning a field on a mirror can be twofold.
 ATObject meta_clone()
          We enforce the restriction that any object has but a single IntrospectiveMirror by returning the mirror itself when asked to clone.
 ATTable meta_getStripes()
          Returns the stripes of this object.
 ATField meta_grabField(ATSymbol fieldName)
          Queries an object for one of its field slots.
 ATMethod meta_grabMethod(ATSymbol methodName)
          Queries an object for one of its method slots.
 ATObject meta_invoke(ATObject receiver, ATSymbol atSelector, ATTable arguments)
          The effect of invoking methods on a mirror (through meta_invoke) consists of checking whether the requested functionality is provided as a meta-operation by the principal that is wrapped by this mirror.
 ATTable meta_listFields()
          Listing the fields of a mirror requires us to list all of the meta_get methods of the principal + all of the base_get methods of the mirror itself
 ATTable meta_listMethods()
          Listing the methods of a mirror requires us to list all of the meta_ methods of the principal (excluding meta_get/set methods) + all of the base_ methods (excluding base_get/set methods) of the mirror itself
 ATObject meta_newInstance(ATTable init)
          This method allows re-initialise a mirror object.
 NATText meta_print()
          Prints out the object in a human-readable way.
 ATBoolean meta_respondsTo(ATSymbol atSelector)
          A mirror responds to a message m if and only if: - either its principal has a method named meta_m - or the mirror itself implements a method named base_m
 ATObject meta_select(ATObject receiver, ATSymbol atSelector)
          The effect of selecting fields or methods on a mirror (through meta_select) consists of checking whether the requested selector matches a field of the principal wrapped by this mirror.
 
Methods inherited from class edu.vub.at.objects.natives.NATByRef
meta_pass, meta_resolve
 
Methods inherited from class edu.vub.at.objects.natives.NATNil
asAmbientTalkObject, asJavaClassUnderSymbiosis, asJavaObjectUnderSymbiosis, asNativeBoolean, asNativeException, asNativeFarReference, asNativeFraction, asNativeNumber, asNativeNumeric, asNativeTable, asNativeText, base__opeql__opeql_, base_asActorMirror, base_asAsyncMessage, base_asBegin, base_asBoolean, base_asClosure, base_asDefinition, base_asExpression, base_asFarReference, base_asField, base_asHandler, base_asMessage, base_asMessageCreation, base_asMethod, base_asNumber, base_asSplice, base_asStatement, base_asStripe, base_asSymbol, base_asTable, base_asUnquoteSplice, base_asVariableAssignment, base_init, base_isBoolean, base_isCallFrame, base_isClosure, base_isFarReference, base_isMessageCreation, base_isMethod, base_isSplice, base_isStripe, base_isSymbol, base_isTable, base_isUnquoteSplice, base_isVariableAssignment, base_new, createChild, equals, isAmbientTalkObject, isJavaObjectUnderSymbiosis, isNativeBoolean, isNativeField, isNativeText, meta_addField, meta_addMethod, meta_assignVariable, meta_defineField, meta_doesNotUnderstand, meta_eval, meta_extend, meta_getDynamicParent, meta_getLexicalParent, meta_isCloneOf, meta_isRelatedTo, meta_isStripedWith, meta_lookup, meta_quote, meta_receive, meta_send, meta_share, readResolve, toString, writeReplace
 
Methods inherited from class java.lang.Object
clone, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 
Methods inherited from interface edu.vub.at.objects.ATObject
base__opeql__opeql_, base_init, base_new, meta_addField, meta_addMethod, meta_assignVariable, meta_defineField, meta_doesNotUnderstand, meta_eval, meta_extend, meta_getDynamicParent, meta_getLexicalParent, meta_isCloneOf, meta_isRelatedTo, meta_isStripedWith, meta_lookup, meta_pass, meta_quote, meta_receive, meta_resolve, meta_send, meta_share
 
Methods inherited from interface edu.vub.at.objects.coercion.ATConversions
asAmbientTalkObject, asJavaClassUnderSymbiosis, asJavaObjectUnderSymbiosis, asNativeBoolean, asNativeException, asNativeFarReference, asNativeFraction, asNativeNumber, asNativeNumeric, asNativeTable, asNativeText, base_asActorMirror, base_asAsyncMessage, base_asBegin, base_asBoolean, base_asClosure, base_asDefinition, base_asExpression, base_asFarReference, base_asField, base_asHandler, base_asMessage, base_asMessageCreation, base_asMethod, base_asNumber, base_asSplice, base_asStatement, base_asStripe, base_asSymbol, base_asTable, base_asUnquoteSplice, base_asVariableAssignment, base_isBoolean, base_isCallFrame, base_isClosure, base_isFarReference, base_isMessageCreation, base_isMethod, base_isSplice, base_isStripe, base_isSymbol, base_isTable, base_isUnquoteSplice, base_isVariableAssignment, isAmbientTalkObject, isJavaObjectUnderSymbiosis, isNativeBoolean, isNativeField, isNativeText
 

Field Detail

principal_

private final ATObject principal_
the object reflected on. This object is NOT a NATMirage

Constructor Detail

NATIntrospectiveMirror

private NATIntrospectiveMirror(ATObject representation)
An introspective mirror is a wrapper which forwards a deified (upped) version of invoked methods and field accesses to its principal. This principal is a Java object representing an ambienttalk object. The deificiation process implies that only the object's meta_level operations (implemented in Java) will be called directly by the mirror.

Parameters:
representation - - the object to reflect upon, which is *not* a NATMirage
Method Detail

atValue

public static final ATMirror atValue(ATObject objectRepresentation)
Return a mirror on the given native or custom AmbientTalk object.

Parameters:
objectRepresentation - the object to reflect upon
Returns:
either an introspective mirror (if the passed object is native), otherwise a custom intercessive mirror.

base_getBase

public ATObject base_getBase()
Description copied from interface: ATMirror
Provides access to the AmbientTalk language value this mirror reflects upon.

Specified by:
base_getBase in interface ATMirror
Returns:
a base-level AmbientTalk object.

base_isMirror

public boolean base_isMirror()
Specified by:
base_isMirror in interface ATConversions
Overrides:
base_isMirror in class NATNil
Returns:
true

base_asMirror

public ATMirror base_asMirror()
Specified by:
base_asMirror in interface ATConversions
Overrides:
base_asMirror in class NATNil
Returns:
this

meta_invoke

public ATObject meta_invoke(ATObject receiver,
                            ATSymbol atSelector,
                            ATTable arguments)
                     throws InterpreterException

The effect of invoking methods on a mirror (through meta_invoke) consists of checking whether the requested functionality is provided as a meta-operation by the principal that is wrapped by this mirror. This implies the requested selector is sought for at the java-level, albeit prefixed with 'meta_'.

Because an explicit AmbientTalk method invocation must be converted into an implicit Java method invocation, the invocation must be deified ('upped'). To uphold stratification of the mirror architecture, the result of this operation should be a mirror on the result of the Java method invocation.

Note that only when the principal does not have a matching meta_level method the mirror itself will be tested for a corresponding base_level method (e.g. used for operators such as ==). In the latter case, stratification is not enforced. This is due to the fact that these operations are not active at the mirror level, they are base-level operations which happen to be applied on a mirror. An added advantage of this technique is that it permits a mirror to give out a reference to its principal.

Specified by:
meta_invoke in interface ATObject
Overrides:
meta_invoke in class NATNil
Throws:
InterpreterException

meta_select

public ATObject meta_select(ATObject receiver,
                            ATSymbol atSelector)
                     throws InterpreterException

The effect of selecting fields or methods on a mirror (through meta_select) consists of checking whether the requested selector matches a field of the principal wrapped by this mirror. If this is the case, the principal's ('meta_get' + selector) method will be invoked. Else the selector might identify one of the principal's meta-operations. If this is the case, then an AmbientTalk representation of the Java method ('meta_' + selector) will be returned.

Because an explicit AmbientTalk method invocation must be converted into an implicit Java method invocation, the invocation must be deified ('upped'). To uphold stratification of the mirror architecture, the result of this operation should be a mirror on the result of the Java method invocation.

Note that only when the principal does not have a matching meta_level field or method the mirror itself will be tested for a corresponding base_level behaviour (e.g. for its base field or for operators such as ==). In the latter case, stratification is not enforced. This is due to the fact that the said fields and methods are not meta-level behaviour, rather they are base-level operations which happen to be applicable on a mirror. An added advantage of this technique is that it permits a mirror to have a field referring to its principal.

Specified by:
meta_select in interface ATObject
Overrides:
meta_select in class NATNil
Throws:
InterpreterException

meta_respondsTo

public ATBoolean meta_respondsTo(ATSymbol atSelector)
                          throws InterpreterException
A mirror responds to a message m if and only if: - either its principal has a method named meta_m - or the mirror itself implements a method named base_m

Specified by:
meta_respondsTo in interface ATObject
Overrides:
meta_respondsTo in class NATNil
Throws:
InterpreterException

meta_assignField

public ATNil meta_assignField(ATObject receiver,
                              ATSymbol name,
                              ATObject value)
                       throws InterpreterException
The effect of assigning a field on a mirror can be twofold. Either a meta_field of the reflectee is altered (in this case, the passed value must be a mirror to uphold stratification). Otherwise it is possible that a base field of the mirror itself is changed.

Specified by:
meta_assignField in interface ATObject
Overrides:
meta_assignField in class NATNil
Throws:
InterpreterException

meta_grabField

public ATField meta_grabField(ATSymbol fieldName)
                       throws InterpreterException
Description copied from interface: ATObject
Queries an object for one of its field slots. Triggers the fieldAccessed event on this object's beholders (mirror observers).

Specified by:
meta_grabField in interface ATObject
Overrides:
meta_grabField in class NATNil
Throws:
InterpreterException

meta_grabMethod

public ATMethod meta_grabMethod(ATSymbol methodName)
                         throws InterpreterException
Description copied from interface: ATObject
Queries an object for one of its method slots. Triggers the methodAccessed event on this object's beholders (mirror observers).

Specified by:
meta_grabMethod in interface ATObject
Overrides:
meta_grabMethod in class NATNil
Throws:
InterpreterException

meta_listFields

public ATTable meta_listFields()
                        throws InterpreterException
Listing the fields of a mirror requires us to list all of the meta_get methods of the principal + all of the base_get methods of the mirror itself

Specified by:
meta_listFields in interface ATObject
Overrides:
meta_listFields in class NATNil
Throws:
InterpreterException

meta_listMethods

public ATTable meta_listMethods()
                         throws InterpreterException
Listing the methods of a mirror requires us to list all of the meta_ methods of the principal (excluding meta_get/set methods) + all of the base_ methods (excluding base_get/set methods) of the mirror itself

Specified by:
meta_listMethods in interface ATObject
Overrides:
meta_listMethods in class NATNil
Throws:
InterpreterException

meta_clone

public ATObject meta_clone()
                    throws InterpreterException
We enforce the restriction that any object has but a single IntrospectiveMirror by returning the mirror itself when asked to clone. The .new(object) operation, which invokes clone, still achieves the wanted behaviour since a new mirror can be properly initialised using base_init. The implementation of this method contacts the factory in order to create a new mirror.

Specified by:
meta_clone in interface ATObject
Overrides:
meta_clone in class NATNil
Throws:
InterpreterException

meta_newInstance

public ATObject meta_newInstance(ATTable init)
                          throws XArityMismatch,
                                 XTypeMismatch
This method allows re-initialise a mirror object. However, since the link from a mirror to its base object is immutable, this results in contacting the mirror factory, to create a (new) mirror for the requested object.

Specified by:
meta_newInstance in interface ATObject
Overrides:
meta_newInstance in class NATNil
Returns:
another (possibly new) mirror object
Throws:
XArityMismatch
XTypeMismatch

meta_print

public NATText meta_print()
                   throws InterpreterException
Description copied from interface: ATObject
Prints out the object in a human-readable way.

Specified by:
meta_print in interface ATObject
Overrides:
meta_print in class NATNil
Throws:
InterpreterException

meta_getStripes

public ATTable meta_getStripes()
                        throws InterpreterException
Description copied from interface: ATObject
Returns the stripes of this object. Note that only the stripes that were attached directly to this object are returned, not all of the parent's stripes as well.

Specified by:
meta_getStripes in interface ATObject
Overrides:
meta_getStripes in class NATNil
Throws:
InterpreterException