at:tutorial:reflection
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revisionNext revisionBoth sides next revision | ||
at:tutorial:reflection [2008/06/23 15:08] – * tvcutsem | at:tutorial:reflection [2008/09/15 17:39] – tvcutsem | ||
---|---|---|---|
Line 3: | Line 3: | ||
[[wp> | [[wp> | ||
- | The reflective model of AmbientTalk is based on [[http:// | + | The reflective model of AmbientTalk is based on [[http:// |
===== Mirrors ===== | ===== Mirrors ===== | ||
- | As we have already | + | |
+ | As we have mentioned in the introduction, | ||
+ | |||
+ | A convenience primitive exists that allows AmbientTalk programmers to acquire a mirror on an object without explicitly having to consult the mirror | ||
+ | |||
+ | Once a mirror has been created, it can be used to inspect | ||
< | < | ||
- | > | + | def Point := object: { |
- | >>< | + | def x := 0; |
- | >mirrorOnOne.listMethods(); | + | def y := 0; |
- | >>[<native method:==>, <native method: | + | def distanceToOrigin() { (x*x + y*y).sqrt }; |
- | < | + | }; |
+ | def p := Point.new(2, | ||
+ | // request a mirror on p via the mirror factory | ||
+ | > def mirrorOnP | ||
+ | >>< | ||
+ | |||
+ | >mirrorOnP.listSlots().map: {|slot| slot.name }; | ||
+ | >>[super, super:=, x, x:=, y, y:=, distanceToOrigin] | ||
</ | </ | ||
- | The code excerpt presented above uses the mirror to // | + | The code excerpt presented above uses the mirror to // |
- | When reflecting upon a user-defined object, we can observe that every object has some implictly defined methods | + | 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 |
< | < | ||
- | >def inspectable | + | // let's add a z coordinate to our point |
- | def map(arg1, @restArgs) { restArgs.map(arg1); } }; | + | def [zaccessor, zmutator] |
- | >>< | + | // we only add the accessor, so the slot is read-only |
- | >def mirrorOnInspectable := reflect: inspectable; | + | mirrorOnP.addSlot(zaccessor); |
- | >><mirror on:< | + | // let's test it: |
- | >mirrorOnInspectable.listFields() | + | > p.z |
- | >>[<field:super>] | + | >> |
- | >mirrorOnInspectable.listMethods() | + | // we can also read slots reflectively: |
- | >>[< | + | > def x :=mirrorOnP.grabSlot(`x) |
- | < | + | >> <accessor method for:x> |
- | >def method := mirrorOnInspectable.grabMethod(`map); | + | > x() |
- | >>< | + | >> |
- | >method.bodyExpression | + | // and we can also invoke methods reflectively: |
- | >> | + | > mirrorOnP.invoke(p, lobby.at.lang.values.createInvocation(`distanceToOrigin, |
+ | >> | ||
+ | // finally, we can remove slots... | ||
+ | > mirrorOnP.removeSlot(`z); | ||
</ | </ | ||
- | Using a mirror on an object, it is possible to get access to a representation of the object' | + | The following example contains |
- | + | ||
- | In addition to allowing a program to reason about the structure of its objects, mirrors can also be used to perform operations such as method invocation in a first-class manner. The following example shows how to select all zero-argument methods whose name starts with '' | + | |
< | < | ||
>def isTestMethod(meth) { | >def isTestMethod(meth) { | ||
| | ||
- | { meth.parameters == [] } }; | + | { meth.parameters.length |
>>< | >>< | ||
>def retainTestMethods(obj) { | >def retainTestMethods(obj) { | ||
Line 52: | Line 65: | ||
>def runTest(obj) { | >def runTest(obj) { | ||
| | ||
- | | + | |
>>< | >>< | ||
> | > | ||
Line 59: | Line 72: | ||
</ | </ | ||
- | This part of the tutorial has provided a basic feeling of how AmbientTalk' | + | This part of the tutorial has provided a basic feeling of how AmbientTalk' |
+ | |||
+ | < | ||
+ | defaultMirror.listSlots.map: | ||
+ | </ | ||
+ | |||
+ | |||
+ | A complete overview of all meta-operations will be presented | ||
===== Mirages ===== | ===== Mirages ===== |
at/tutorial/reflection.txt · Last modified: 2010/11/16 16:32 by tvcutsem