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:31]
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 =====
at/tutorial/objects.1185546709.txt.gz · Last modified: 2007/08/04 11:02 (external edit)