User Tools

Site Tools


at:tutorial:objects

Differences

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

Link to this comparison view

Both sides previous revisionPrevious revision
Next revisionBoth sides next revision
at:tutorial:objects [2007/07/10 22:04] – expanded tvcutsemat:tutorial:objects [2007/07/10 22:14] – changed tvcutsem
Line 152: Line 152:
 </note> </note>
  
-===== First-class delegation ===== +===== First-class Delegation ===== 
-AmbientTalk provides a special message-sending operator ''^'' (the "caret" or "hat" symbol) to express the //explicit// delegation of a message to an object. The code below illustrates the use of the ''^'' operator in the implementation of the ''init'' method of the ''point3D'' object.+ 
 +AmbientTalk provides a special message-sending operator ''^'' (the "caret" or "hat" symbol) to express the //explicit// delegation of a message to an object. The code below illustrates the use of the ''^'' operator
 + 
 +<code> 
 +def Enumerable := object: { 
 +  def collect: closure { 
 +    def c := clone: self; 
 +    self.each: { |v| 
 +      c.add(closure(v)) 
 +    }; 
 +  }; 
 +}; 
 +def Array := object: { 
 +  def elements := []; 
 +  def init() { ... }; 
 +  def collect: closure { 
 +    Enumerable^collect: closure; 
 +  }; 
 +  def each: clo { 
 +    1.to: elements.length do: { |i| 
 +      clo(elements[i]) 
 +    }; 
 +  }; 
 +}; 
 +</code> 
 + 
 +A message sent to an object using the ''^'' symbol (e.g. to the ''Enumerable'' object in the example above) will start the method lookup in this object and execute the method body with the ''self'' pseudovariable **left unchanged** to the message sender. In the code example above, when ''collect:'' is invoked on an ''Array'' object, the array object //delegates// the message to the ''Enumerable'' object. As such, method lookup starts in ''Enumerable'', finds the method there, and then invokes it with ''self'' left bound to the ''Array'' object. Hence, the ''self.each:'' send in the ''Enumerable'' object uses ''Array'''s definition of ''each:'' to generate the elements in the collection. 
 + 
 +Of course, the example above is a bit contrived: we could have just assigned ''Enumerable'' as the parent of ''Array'' such that we would not even have to write the "delegating" ''collect:'' method in ''Array''. However, what the explicit ''^'' delegation operator allows is the expression of patterns resembling //multiple inheritance// where some requests are delegated to one object, while other methods can be delegated to other objects. Explicit delegation enables the expression of delegation patterns which would be awkward or difficult to express using only single (delegation-based) inheritance.
  
 <code> <code>
-def point3D := extend: point with: {+def Point3D := extend: Point with: {
   def z := 0;   def z := 0;
   def init(aX, aY, aZ) {   def init(aX, aY, aZ) {
Line 162: Line 190:
     z := aZ;     z := aZ;
   };   };
-}+};
 </code> </code>
  
-A message sent to an object using the ''^'' symbol (e.g. to the parent object in the example above) will start the method lookup in this object (and its parents) and then execute the method body with the ''self'' pseudovariable bound to the message sender. 
  
 <note warning> <note warning>
at/tutorial/objects.txt · Last modified: 2013/05/17 20:23 by tvcutsem