From 5af9d6a919b83e28a37ade2db8090a375a93ba53 Mon Sep 17 00:00:00 2001 From: Steve Bennett Date: Mon, 1 Aug 2022 09:19:52 +1000 Subject: oo: better object construction Now a default constructor is created, as an alias for defaultconstrutor. The constructor is passed the arguments to new and by default this accepts a dictionary that is checked for valid instance variables and sets them. However the constructor can be replaced by one that takes arbitrary arguments. Thus we can how have: a new -optiona -optionb And the constructor is invoked with arguments '-optiona -optionab'. This makes object initialisation more flexible. ** Note: This is an incompatible change if you have classes with a constructor and you create object instances with new . Signed-off-by: Steve Bennett Documentation fixes - Co-authored-by: Adrian Ho --- examples/ootest.tcl | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) (limited to 'examples') diff --git a/examples/ootest.tcl b/examples/ootest.tcl index 731e46a..b0b3665 100644 --- a/examples/ootest.tcl +++ b/examples/ootest.tcl @@ -13,12 +13,13 @@ puts "Account vars=[Account vars]" puts "Account methods=[Account methods]" puts "" -# Create a constructor. This does validation, but it could -# do other things -Account method constructor {} { - if {$balance < 0} { - error "Can't initialise account with a -ve balance" +# Create a constructor that takes a name and an optional balance. +Account method constructor {who {amount 0}} { + if {$amount < 0} { + error "Can't initialise account for $who with a -ve balance" } + set name $who + set balance $amount } # Now flesh out the class with some methods @@ -42,8 +43,16 @@ Account method describe {} { } } -# Now an instance, initialisition some fields -set a [Account new {name "Bob Smith"}] +# Since the constructor requires an argument, can't +# not provide them +try { + set a [Account] +} on error msg { + puts "Correctly did not create uninitialised account" +} + +# Now an instance, using the constructor for initialisation +set a [Account new "Bob Smith"] puts "---- object Account ----" # We can use class methods on the instance too @@ -70,10 +79,11 @@ class CreditAccount Account { limit -1000 } -CreditAccount method constructor {} { - # Dummy constructor - # If desired, manually invoke the baseclass constructor - super constructor +CreditAccount method constructor {who {amount 0}} { + # Invoke the baseclass constructor, then + # set the amount, which may be -ve + super constructor $who + set balance $amount } # Override the 'withdraw' method to allow overdrawing @@ -96,7 +106,7 @@ puts "CreditAccount methods=[CreditAccount methods]" puts "" puts "---- object CreditAccount ----" -set b [CreditAccount new {name "John White"}] +set b [CreditAccount new "John White" -20] puts b.vars=[$b vars] puts b.classname=[$b classname] @@ -128,8 +138,8 @@ puts "Total of accounts [$a get name] and [$b eval {return "$name (Credit Limit: # Almost. We can't really distinguish those which aren't real classes. # This will get all references which aren't simple lambdas. puts "---- All objects ----" -Account new {name "Terry Green" balance 20} -set x [Account] +Account new "Terry Green" 20 +set x [Account new -] lambda {} {dummy} ref blah blah -- cgit v1.1