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 revision
Previous revision
Next revisionBoth sides next revision
at:tutorial:objects [2007/07/10 22:29] – * tvcutsemat:tutorial:objects [2007/07/18 18:30] jorge
Line 94: Line 94:
   def z := 0;   def z := 0;
   def sumOfSquares() {   def sumOfSquares() {
-    super^sumOfSquares() + z*z+    super^sumOfSquares() + z*z;
   };   };
 } }
Line 159: Line 159:
 def Enumerable := object: { def Enumerable := object: {
   def collect: closure {   def collect: closure {
-    def c := clone: self;+    def c := self.new([]);
     self.each: { |v|     self.each: { |v|
-      c.add(closure(v))+      c.add(closure(v));
     };     };
 +    c;
   };   };
 }; };
 def Array := object: { def Array := object: {
   def elements := [];   def elements := [];
-  def init() { ... };+  def init(a) { elements := a; }; 
 +  def add(v) { elements := elements + [v]; self };
   def collect: closure {   def collect: closure {
     Enumerable^collect: closure;     Enumerable^collect: closure;
   };   };
   def each: clo {   def each: clo {
-    1.to: elements.length do: { |i| +    1.to: elements.length + 1 do: { |i| 
-      clo(elements[i])+      clo(elements[i]);
     };     };
   };   };
Line 181: Line 183:
 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. 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. In [[:at:tutorial:modular|a later chapter]], we will show how ''^'' forms the basis for advanced //trait composition//.+<code> 
 +> Array.add(1).add(2).add(3) 
 +>> <object:11698353> 
 +> def c := Array.collect: { |v| v+1 } 
 +>> <object:14179973> 
 +> c.each: { |v| system.print(v)} 
 +
 +
 +
 +>>nil 
 +</code> 
 + 
 +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. In [[:at:tutorial:modular#objects_as_traits|a later chapter]], we will show how ''^'' forms the basis for advanced //trait composition//.
  
 Having described the semantics of ''^'', we can now turn our attention to "super-sends". In AmbientTalk, a traditional "super-send" (ala Java or Smalltalk) is expressed as explicit delegation to the ''super'' object. For example, here is how to properly initialize parent objects from child objects: Having described the semantics of ''^'', we can now turn our attention to "super-sends". In AmbientTalk, a traditional "super-send" (ala Java or Smalltalk) is expressed as explicit delegation to the ''super'' object. For example, here is how to properly initialize parent objects from child objects:
at/tutorial/objects.txt · Last modified: 2013/05/17 20:23 by tvcutsem