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 revision Previous revision
Next revision
Previous revision
at:tutorial:objects [2007/07/27 16:27]
tvcutsem *
at:tutorial:objects [2013/05/17 20:23] (current)
tvcutsem updated
Line 174: Line 174:
   };   };
   def each: clo {   def each: clo {
-    1.to: elements.length + 1 do: { |i|+    1.to: elements.length do: { |i|
       clo(elements[i]);       clo(elements[i]);
     };     };
Line 184: Line 184:
  
 <code> <code>
-Array.add(1).add(2).add(3) +Array.add(1).add(2).add(3) 
->> <object:11698353> +def c := Array.collect: { |v| v+1 } 
-def c := Array.collect: { |v| v+1 } +c.each: { |v| system.print(v)} // prints 234
->> <object:14179973> +
-c.each: { |v| system.print(v)} +
-234 +
->>nil+
 </code> </code>
  
Line 233: Line 229:
 > makeBankAccount(100).balance; > makeBankAccount(100).balance;
 >>Lookup failure : selector balance could not be found in  >>Lookup failure : selector balance could not be found in 
-  <object:5068254>+  <obj:{super,super:=,deposit}>
 </code> </code>
 +
 +This pattern of creating objects by means of "constructor functions" rather than by cloning and instantiating prototypes is often very useful in its own right. However, when creating objects that use their lexical scope to hold their state, be aware of the following issue when you mix object creation via instantiation and object creation via cloning: clones //share// their lexical scope! Hence, given a bank account object ''b'', the following leads to erroneous behaviour:
 +
 +<code>
 +def b := makeBankAccount(100);
 +def b2 := b.new(); // shares its balance field with b!
 +b.deposit(10); // affects b2 as well!
 +</code>
 +
 +In order to prevent this kind of errors, it is considered best practice to override ''new'' for objects that should be solely defined by means of constructor functions, as follows:
 +
 +<code>
 +def makeBankAccount(balance) {
 +  object: {
 +    def new(@args) { makeBankAccount(@args) };
 +    def deposit(amnt) { /* as before */ };
 +  }
 +}
 +</code>
 +
 +By overriding ''new'' and calling the constructor function, this code ensures that code such as ''aBankAccount.new(10)'' will result in a proper new bank account object with its own private lexical scope to store its state.
  
 ===== Uniform Access ===== ===== Uniform Access =====
Line 291: Line 308:
 </code> </code>
  
-When explicitly //applying// the ''x'' field, the interpreter //does// execute the block closure stored in ''x''. If the interpreter would not behave in this way, but rather have ''o.x()'' return the closure as well, then the programmer would be required to write ''(o.x)()'', which is a bit clumsy. In essence, the rule remains simple: code of the form ''o.x'' either returns the value of a //field// ''x'' or executes a //method// ''x''. Whether or not the field contains a closure does not change the semantics.+When explicitly //applying// the ''x'' field, the interpreter //does// execute the block closure stored in ''x''. If the interpreter would not behave in this way, but rather have ''o.x()'' return the closure as well, then the programmer would be required to write ''(o.x)()'' to apply the closure, which is a bit clumsy. In essence, the rule remains simple: code of the form ''o.x'' either returns the value of a //field// ''x'' or executes a //method// ''x''. Whether or not the field contains a closure does not change the semantics.
  
 ==== UAP and Assignment ==== ==== UAP and Assignment ====
Line 317: Line 334:
   // and a mutator method seconds:=(v)   // and a mutator method seconds:=(v)
  
-  def minutes() { (seconds / 60}; +  def minutes() { seconds / 60 }; 
-  def hours()   (seconds / 3600};+  def hours()   { seconds / 3600 };
  
   def minutes:=(mins) {   def minutes:=(mins) {
Line 334: Line 351:
 >> 3600 >> 3600
 > time.seconds := 180 > time.seconds := 180
 +>> 180
 > time.minutes > time.minutes
 >> 2 >> 2
at/tutorial/objects.1185546446.txt.gz · Last modified: 2007/07/27 16:28 (external edit)