232 THE RUN-TIME STRUCTURE:OBJECTS $8.3 objects as needed at run time,according to a pattern which is usually impossible to predict by a mere static examination of the software text. From an initial state in which (as described in the previous chapter)only one object has been created-the root object-a system will repetitively perform such operations on the object structure as creating a new object,attach a previously void reference to an object,make a reference void,or reattach a previously attached reference to a different object.The dynamic and unpredictable nature of these operations is part of the reason for the flexibility of the approach,and its ability to support the dynamic data structures that are necessary if we are to use advanced algorithms and model the fast-changing properties of many external systems. The next sections explore the mechanisms needed to create objects and manipulate their fields,in particular references. The creation instruction Let us see how to create an instance of a class such as BOOK3.This can only be done by a routine of a class which is a client of BOOK3,such as class QUOTATION feature source:BOOK3 page:INTEGER make book is -Create a BOOK3 object and attach source to it. do ..See below .. end end which might serve to describe a quotation of a book,appearing in another publication and identified by two fields:a reference to the quoted book and the number of the page which quotes the book. The(soon to be explained)mechanism that creates an instance oftype OUOTATION will also by default initialize all its fields.An important part of the default initialization rule is that any reference field,such as the one associated with attribute source,will be initialized to a void reference.In other words,creating an object of type QUOTATION does not by itself create an object of type BOOK3. The general rule is indeed that,unless you do something to it,a reference remains void.To change this,you may create a new object through a creation instruction.This can be done by procedure make book,which should then read as follows:
232 THE RUN-TIME STRUCTURE: OBJECTS §8.3 objects as needed at run time, according to a pattern which is usually impossible to predict by a mere static examination of the software text. From an initial state in which (as described in the previous chapter) only one object has been created — the root object — a system will repetitively perform such operations on the object structure as creating a new object, attach a previously void reference to an object, make a reference void, or reattach a previously attached reference to a different object. The dynamic and unpredictable nature of these operations is part of the reason for the flexibility of the approach, and its ability to support the dynamic data structures that are necessary if we are to use advanced algorithms and model the fast-changing properties of many external systems. The next sections explore the mechanisms needed to create objects and manipulate their fields, in particular references. The creation instruction Let us see how to create an instance of a class such as BOOK3. This can only be done by a routine of a class which is a client of BOOK3, such as class QUOTATION feature source: BOOK3 page: INTEGER make_book is -- Create a BOOK3 object and attach source to it. do … See below … end end which might serve to describe a quotation of a book, appearing in another publication and identified by two fields: a reference to the quoted book and the number of the page which quotes the book. The (soon to be explained) mechanism that creates an instance of type QUOTATION will also by default initialize all its fields. An important part of the default initialization rule is that any reference field, such as the one associated with attribute source, will be initialized to a void reference. In other words, creating an object of type QUOTATION does not by itself create an object of type BOOK3. The general rule is indeed that, unless you do something to it, a reference remains void. To change this, you may create a new object through a creation instruction. This can be done by procedure make_book, which should then read as follows:
$8.3 MANIPULATING OBJECTS AND REFERENCES 233 make book is --Create a BOOK3 object and attach source to it. do source end This illustrates the simplest form of the creation instruction:!x,where x is an attribute of the enclosing class or(as will be seen later)a local entity of the enclosing routine.We will see a few extensions to this basic notation later. The symbol is usually read aloud as"bang",so that !is"bang bang".The entityx named in the instruction (source in the above example)is called the target of the creation instruction. This form of the creation instruction is known as a "basic creation instruction". (Another form,involving a call to a procedure of the class,will appear shortly.)Here is the precise effect of a basic creation instruction: Effect of a basic creation instruction The effect of a creation instruction of the form !!x,where the type of the target x is a reference type based on a class C,is to execute the following three steps: C1.Create a new instance of C(made of a collection of fields,one for each attribute of C).Let OC be the new instance. The“standard C2.Initialize each field of OC according to the standard default values. default values" mentioned in step C3.Attach the value ofx(a reference)to OC. C2 appear in the next box. Step CI will create an instance of C.Step C2 will set the values of each field to a predetermined value,which depends on the type of the corresponding attribute.Here are these values: Default initialization values For a reference,the default value is a void reference. For a BOOLEAN,the default value is False. For a CHARACTER,the default value is the null character. For a number(of type INTEGER,REAL or DOUBLE),the default value is zero (that is to say,the zero value of the appropriate type)
§8.3 MANIPULATING OBJECTS AND REFERENCES 233 make_book is -- Create a BOOK3 object and attach source to it. do !! source end This illustrates the simplest form of the creation instruction: !! x, where x is an attribute of the enclosing class or (as will be seen later) a local entity of the enclosing routine. We will see a few extensions to this basic notation later. The symbol ! is usually read aloud as “bang”, so that !! is “bang bang”. The entity x named in the instruction (source in the above example) is called the target of the creation instruction. This form of the creation instruction is known as a “basic creation instruction”. (Another form, involving a call to a procedure of the class, will appear shortly.) Here is the precise effect of a basic creation instruction: Step C1 will create an instance of C. Step C2 will set the values of each field to a predetermined value, which depends on the type of the corresponding attribute. Here are these values: Effect of a basic creation instruction The effect of a creation instruction of the form !! x, where the type of the target x is a reference type based on a class C, is to execute the following three steps: C1 • Create a new instance of C (made of a collection of fields, one for each attribute of C). Let OC be the new instance. C2 • Initialize each field of OC according to the standard default values. C3 • Attach the value of x (a reference) to OC. Default initialization values For a reference, the default value is a void reference. For a BOOLEAN, the default value is False. For a CHARACTER, the default value is the null character. For a number (of type INTEGER, REAL or DOUBLE), the default value is zero (that is to say, the zero value of the appropriate type). The “standard default values” mentioned in step C2 appear in the next box
234 THE RUN-TIME STRUCTURE:OBJECTS $8.3 So for a target source of type BOOK3,where the above class declaration read class BOOK3 feature title:STRING date,page count:INTEGER author:WRITER end the creation instruction !source,executed as part of a call to procedure make book of class OUOTATION,will yield an object of the following form: title A newly created and date 0 initialized page count 0 object author (BOOK3) The integer fields have been initialized to zero.The reference field for author has "STRINGS".13.5. been initialized to a void reference.The field for title,a STRING,also shows a void page 456. reference.This is because type STRING (of which the above initialization rules said nothing)is in fact a reference type too,although as noted we may for most practical purposes treat it as a basic type. The global picture It is important not to lose track of the order in which things happen.For the above instance of BOOK3 to be created,the following two events must occur: B1.An instance of QUOTATION gets created.Let Q_OBJ be that instance and let a be an entity whose value is a reference attached to Q_OBJ. B2.Some time after step B1,a call ofthe form a.make book executes procedure make book with Q OBJ as its target. It is legitimate of course to ask how we ever get to step B1-how Q OBJ itself will See "PUTTING be created.This only pushes the problem further.But by now you know the answer to this EVERYTHING question:it all comes back to the Big Bang.To execute a system,you must provide a root TOGETHER”,7.9 page 194. class and the name of a procedure of that class,the creation procedure.At the start of the execution,you are automatically provided with one object,the root object-an instance of the root class.The root object is the only one that does not need to be created by the software text itself,it comes from the outside,as an objectus ex machina.Starting with that one providential object,the software can now create other objects in the normal way, through routines that execute creation instructions.The first routine to be executed is the creation procedure,automatically applied to the root object;in all but the most trivial cases it will include at least one creation instruction so as to start what the previous chapter compared to a giant firework:the process of producing as many new objects as a particular execution will need
234 THE RUN-TIME STRUCTURE: OBJECTS §8.3 So for a target source of type BOOK3, where the above class declaration read class BOOK3 feature title: STRING date, page_count: INTEGER author: WRITER end the creation instruction !! source, executed as part of a call to procedure make_book of class QUOTATION, will yield an object of the following form: The integer fields have been initialized to zero. The reference field for author has been initialized to a void reference. The field for title, a STRING, also shows a void reference. This is because type STRING (of which the above initialization rules said nothing) is in fact a reference type too, although as noted we may for most practical purposes treat it as a basic type. The global picture It is important not to lose track of the order in which things happen. For the above instance of BOOK3 to be created, the following two events must occur: B1 • An instance of QUOTATION gets created. Let Q_OBJ be that instance and let a be an entity whose value is a reference attached to Q_OBJ. B2 • Some time after step B1, a call of the form a ● make_book executes procedure make_ book with Q_OBJ as its target. It is legitimate of course to ask how we ever get to step B1 — how Q_OBJ itself will be created. This only pushes the problem further. But by now you know the answer to this question: it all comes back to the Big Bang. To execute a system, you must provide a root class and the name of a procedure of that class, the creation procedure. At the start of the execution, you are automatically provided with one object, the root object — an instance of the root class. The root object is the only one that does not need to be created by the software text itself; it comes from the outside, as an objectus ex machina. Starting with that one providential object, the software can now create other objects in the normal way, through routines that execute creation instructions. The first routine to be executed is the creation procedure, automatically applied to the root object; in all but the most trivial cases it will include at least one creation instruction so as to start what the previous chapter compared to a giant firework: the process of producing as many new objects as a particular execution will need. A newly created and initialized object 0 title date (BOOK3) page_count 0 author “STRINGS”, 13.5, page 456. See “PUTTING EVERYTHING TOGETHER”, 7.9, page 194
$8.3 MANIPULATING OBJECTS AND REFERENCES 235 Why explicit creation? Object creation is explicit.Declaring an entity such as b:BOOK3 does not cause an object to be created at run time:creation will only occur when some element of the system executes an operation !!b You may have wondered why this was so.Should the declaration of b not be sufficient if we need an object at run time?What good is it to declare an entity if we do not create an object? A moment's reflection,however,shows that the distinction between declaration and creation is actually the only reasonable solution. The first argument is by reductio ad absurdum.Assume that somehow we start processing the declaration of b and immediately create the corresponding book object.But this object is an instance of class BOOK3,which has an attribute author,itself of a reference type WR/TER,so that the author field is a reference,for which we must create an object right away.Now this object has reference fields(remember that STRING is in fact a reference type)and they will require the same treatment:we are starting on a long path of recursive object creation before we have even begun any useful processing! This argument would be even more obvious with a self-referential class,such as PERSONI seen above: class PERSONI feature name:STRING loved one,landlord:PERSONI end Treating every declaration as yielding an object would mean that every creation of an instance of PERSON/would cause creation of two more such objects(corresponding to loved one and landlord),entering into an infinite loop.Yet we have seen that such self- referential definitions,either direct as here or indirect,are common and necessary. Another argument simply follows from a theme that runs through this chapter:the use of object technology as a powerful modeling technique.If every reference field were initialized to a newly created object,we would have room neither for void references nor for multiple references attached to a single object.Both are needed for realistic modeling of practical systems: In some cases the model may require that a certain reference be left not attached to any object.We used this technique when leaving the author field void to indicate that a book is by an unknown author. See the figure on In other cases two references should be attached,again for conceptual reasons page 226. coming from the model,to the same object.In the self-reference example we saw the loved one fields of two PERSON/instances attached to the same object.It would
§8.3 MANIPULATING OBJECTS AND REFERENCES 235 Why explicit creation? Object creation is explicit. Declaring an entity such as b: BOOK3 does not cause an object to be created at run time: creation will only occur when some element of the system executes an operation !! b You may have wondered why this was so. Should the declaration of b not be sufficient if we need an object at run time? What good is it to declare an entity if we do not create an object? A moment’s reflection, however, shows that the distinction between declaration and creation is actually the only reasonable solution. The first argument is by reductio ad absurdum. Assume that somehow we start processing the declaration of b and immediately create the corresponding book object. But this object is an instance of class BOOK3, which has an attribute author, itself of a reference type WRITER, so that the author field is a reference, for which we must create an object right away. Now this object has reference fields (remember that STRING is in fact a reference type) and they will require the same treatment: we are starting on a long path of recursive object creation before we have even begun any useful processing! This argument would be even more obvious with a self-referential class, such as PERSON1 seen above: class PERSON1 feature name: STRING loved_one, landlord: PERSON1 end Treating every declaration as yielding an object would mean that every creation of an instance of PERSON1 would cause creation of two more such objects (corresponding to loved_one and landlord), entering into an infinite loop. Yet we have seen that such selfreferential definitions, either direct as here or indirect, are common and necessary. Another argument simply follows from a theme that runs through this chapter: the use of object technology as a powerful modeling technique. If every reference field were initialized to a newly created object, we would have room neither for void references nor for multiple references attached to a single object. Both are needed for realistic modeling of practical systems: • In some cases the model may require that a certain reference be left not attached to any object. We used this technique when leaving the author field void to indicate that a book is by an unknown author. • In other cases two references should be attached, again for conceptual reasons coming from the model, to the same object. In the self-reference example we saw the loved_one fields of two PERSON1 instances attached to the same object. It would See the figure on page 226
236 THE RUN-TIME STRUCTURE:OBJECTS $8.4 not make sense in that case to create an object for each field on creation;what you need is,rather than a creation instruction,an assignment operation(studied later in this chapter)that attaches a reference to an already existing object.This observation applies even more clearly to the self-referential field from the same example (field landlord for the top object). The object management mechanism never attaches a reference implicitly.It creates objects through creation instructions (or clone operations,seen below and explicit too), initializing their reference fields to void references;only through explicit instructions will these fields,in turn,become attached to objects. In the discussion of inheritance we will see that a creation instruction may use the syntax “Polymorphic cre- T x to create an object whose type T is a descendant of the type declared for x. aion”,page479. 8.4 CREATION PROCEDURES All the creation instructions seen so far relied on default initializations.In some cases,you may be unhappy with the language-defined initializations,wanting instead to provide specific information to initialize the created object.Creation procedures address this need. Overriding the default initializations To use an initialization other than the default,give the class one or more creation procedures.A creation procedure is a procedure of the class,which is listed in a clause starting with the keyword creation at the beginning of the class,before the first feature clause.The scheme is this: indexing class C creation pl.p2.... feature ..Feature declarations,including declarations for procedures pl,p2,... end A style suggestion:the recommended name for creation procedures in simple cases is “CHOOSING THE make,for a class that has only one creation procedure;for a class that has two or more RIGHT NAMES”, creation procedures it is generally desirable to give them a name starting with make and 26.2,page879. continuing with some qualifying word,as in the POIN7 example that follows The corresponding creation instruction is not just !!x any more,but of the form !!x.p(...) where p is one of the creation procedures listed in the creation clause,and (...)is a valid actual argument list for p.The effect of such an instruction is to create the object using the default values as in the earlier form,and to apply p,with the given arguments,to the result. The instruction is called a creation call;it is a combination of creation instruction and procedure call
236 THE RUN-TIME STRUCTURE: OBJECTS §8.4 not make sense in that case to create an object for each field on creation; what you need is, rather than a creation instruction, an assignment operation (studied later in this chapter) that attaches a reference to an already existing object. This observation applies even more clearly to the self-referential field from the same example (field landlord for the top object). The object management mechanism never attaches a reference implicitly. It creates objects through creation instructions (or clone operations, seen below and explicit too), initializing their reference fields to void references; only through explicit instructions will these fields, in turn, become attached to objects. In the discussion of inheritance we will see that a creation instruction may use the syntax ! T ! x to create an object whose type T is a descendant of the type declared for x. 8.4 CREATION PROCEDURES All the creation instructions seen so far relied on default initializations. In some cases, you may be unhappy with the language-defined initializations, wanting instead to provide specific information to initialize the created object. Creation procedures address this need. Overriding the default initializations To use an initialization other than the default, give the class one or more creation procedures. A creation procedure is a procedure of the class, which is listed in a clause starting with the keyword creation at the beginning of the class, before the first feature clause. The scheme is this: indexing … class C creation p1, p2, … feature … Feature declarations, including declarations for procedures p1, p2, … end A style suggestion: the recommended name for creation procedures in simple cases is make, for a class that has only one creation procedure; for a class that has two or more creation procedures it is generally desirable to give them a name starting with make_ and continuing with some qualifying word, as in the POINT example that follows. The corresponding creation instruction is not just !! x any more, but of the form !! x ● p (…) where p is one of the creation procedures listed in the creation clause, and (…) is a valid actual argument list for p. The effect of such an instruction is to create the object using the default values as in the earlier form, and to apply p, with the given arguments, to the result. The instruction is called a creation call; it is a combination of creation instruction and procedure call. “Polymorphic creation”, page 479. “CHOOSING THE RIGHT NAMES”, 26.2, page 879