User Tools

Site Tools


at:tutorial:reflection

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
Next revisionBoth sides next revision
at:tutorial:reflection [2008/09/15 17:36] tvcutsemat:tutorial:reflection [2008/09/15 17:58] – rewritten tvcutsem
Line 28: Line 28:
 </code> </code>
  
-The code excerpt presented above uses the mirror to //introspect// on an object and uses the ''listSlots'' meta-method. The result is a table of the slots (fields and methods) provided by this object. Notice that fields are represented as a combination of an accessor and a mutator method, conforming to the Uniform Access Principle as discussed in chapter 5. Also note that the object has a field called ''super'', although this field was not explicitly defined. In AmbientTalk, ''super'' is defined implicitly for every object.+The code excerpt presented above uses the mirror to //introspect// on an object and uses the ''listSlots'' meta-method. The result is a table of the slots (fields and methods) provided by this object. Notice that fields are represented as a combination of an accessor and a mutator method, conforming to the Uniform Access Principle as discussed in [[:at:tutorial:objects#uniform_access|chapter 5]]. Also note that the object has a field called ''super'', although this field was not explicitly defined. In AmbientTalk, ''super'' is defined implicitly for every object.
  
 The code excerpt below shows how one can add and remove slots to and from an object, and how one can explicitly access values and invoke methods upon an object, reflectively: The code excerpt below shows how one can add and remove slots to and from an object, and how one can explicitly access values and invoke methods upon an object, reflectively:
Line 72: Line 72:
 </code> </code>
  
-This part of the tutorial has provided a basic feeling of how AmbientTalk's default mirrors can be created and the kind of power they offer. The default mirrors offer a much wider range of capabilities than those presented in this section, however. A complete overview of all meta-operations will be presented in the final chapter of this tutorial.+This part of the tutorial has provided a basic feeling of how AmbientTalk's default mirrors can be created and the kind of power they offer. The default mirrors offer a much wider range of capabilities than those presented in this section, however. To get a complete overview, try to inspect AmbientTalk's prototypical mirror, named ''defaultMirror'', e.g. by using introspection: 
 + 
 +<code> 
 +defaultMirror.listSlots.map: { |slot| slot.name } 
 +</code> 
 + 
 + 
 +A complete overview of all meta-operations will be presented near the end of this chapter and can also be found in the [[http://prog.vub.ac.be/amop/at2langref/edu/vub/at/objects/MirrorRoot.html|language reference]].
  
 ===== Mirages ===== ===== Mirages =====
-Extending the AmbientTalk core language involves adding objects which have a different implementation for some of the default meta-operations. In this part of the tutorial, we describe how a programmer could define objects which allow for the dynamic addition of unknown methods and fields. First of all, we need to create a mirror instance which we can use to create new objects fromThis can be performed using the ''mirror:'' language construct as follows.+ 
 +Extending the AmbientTalk core language involves adding objects which have a different implementation for some of the default meta-operations. In this part of the tutorial, we describe how a programmer can redefine the programming language's default semantics of the MOP, by means of mirages. 
 + 
 +As a simple example, we show how to trace all method calls made on an object. The first step is to define //mirror// object that encapsulates this logging behaviourA mirror object must implement the complete AmbientTalk MOP. To make it convenient to make small changes to the MOP, AmbientTalk provides the ''defaultMirror'', which encapsulates the default semantics. By selectively overriding this mirror's methods, we can make small adjustments to the language, e.g. as follows:
  
 <code> <code>
-def dynamicExtensionMirror := mirror: { +def createTracingMirror(baseObject) { 
-  def doesNotUnderstand(selector) { +  extenddefaultMirror with: { 
-    system.println("You selected a slot" + selector + "which does not exist in this object."); +    def invoke(slf, invocation) { 
-    system.println("You can provide a definition here or press enter to report this error."); +      system.println("invoked "+invocation.selector+" on "+baseObject); 
-    def input := system.readln(); +      super^invoke(slf, invocation); 
-    if: !( "" == input ) then: { +    } 
-      def definition := read: input; +  }
-      eval: definition in: base; +
-    } else: { +
-      super^doesNotUnderstand(selector); +
-    }; +
-  };+
 } }
 </code> </code>
  
-<note> **TODO** Add a word on **base** </note>+The primitive ''mirror:'' is syntactic sugar for extending from the ''defaultMirror'', allowing the above example to be rewritten as:
  
-This mirror overrides the default implementation of the meta-operation ''doesNotUnderstand'' to report that a slot was selected which did not existThe user is then provided with an opportunity to provide the missing definition or pass this opportunity in which case the default behaviour is executed (i.e. an error is being reported)The mirror defined above can be used subsequently to create objects with an adapted meta-object protocolSuch objects are called **mirages** as they are not ordinary objects, but rather objects whose appearance and behaviour are defined by a custom mirror. Mirages are constructed using a variation on the ''object:'' constructor as is illustrated below.+<code> 
 +def createTracingMirror(baseObject) { 
 +  mirror: { 
 +    def invoke(slf, invocation) { 
 +      system.println("invoked "+invocation.selector+" on "+baseObject)
 +      super^invoke(slf, invocation); 
 +    } 
 +  } 
 +
 +</code> 
 + 
 +The next step is to create objects whose method calls can be tracedThese objects will require the above tracing mirror as their implicit mirror. We call such objects with a custom implicit mirror **mirages**. Mirages are constructed using a variation on the ''object:'' constructor as is illustrated below.
  
 <code> <code>
 def mirage := object: { def mirage := object: {
-  def m() { self.x }; +  def foo() { 42 }; 
-} mirroredBy: dynamicExtensionMirror;+} mirroredBy:{ |emptyBase| createTracingMirror(emptyBase) };
 </code> </code>
  
-When invoking the method ''m'' on the mirage, ''doesNotUnderstand'' will be invoked with selector ''`x''since the object does not have slot with the request name. The user can mediate this oversight by typing ''def x := 5'' at which point the slot will be added to the objectUsing the code from the previous section, the user can verify that the mirage object now sports both an ''x'' and an ''x:='' slot+In the code above, the closure passed to ''mirroredBy:'' is //mirror construction closure//. This closure is applied to a newempty mirage object and it is expected that it returns new mirror that reflects upon this mirageWhen the mirror is constructed, the object initialization closure is executed.
  
-<note> +When invoking the method ''m'' on the mirage, ''invoke'' will be invoked on the tracing mirror, causing the following behaviour: 
-Note that the use of ''self.x'' in the above example is crucial as the ''doesNotUnderstand'' operation is not called when a lexical lookup fails+ 
-</note>+<code> 
 +> mirage.m(); 
 +invoked m on <obj:6276614{foo,...}> 
 +>> 42 
 +</code>
  
-Whereas the example provided above may seem a little contrived, the reflective capabilities of AmbientTalk allow it to be extended with many abstraction relating to distributed computing for mobile ad hoc networks (AmbientTalk's main domain of application). An example of a language construct which is conceived as a reflective extension to the language is for instance futures, which are discussed in the next chapter of this tutorial.+Whereas the example provided above may seem a little contrived, the reflective capabilities of AmbientTalk allow it to be extended with many abstraction relating to distributed computing for mobile ad hoc networks (AmbientTalk's main domain of application). An example language construct which is conceived as a reflective extension to the language is that of future-type message passing. Futures are discussed in the next chapter of this tutorial.
  
 ===== The Metaobject Protocol ===== ===== The Metaobject Protocol =====
at/tutorial/reflection.txt · Last modified: 2010/11/16 16:32 by tvcutsem