Constructed types: additional details

Data entry

When entering data into a constructed type, remember that data must always be positioned relative to both the host class and the constructed type. Here are two more examples.

In the first example, the constructed type has no fields, just labels. The data consists of a label from ?TShirt (Color) and a label from ?Choices (teal):

?TShirt Color #Choices

?Choices Beige
         Mauve
         Teal

TShirt : Sam47
Color Teal

The second example shows what happens when a constructed type itself contains a constructed type. In this case each constructed type requires a label for positioning, so three labels are involved: one from ?Locus (Location), one from ?map_location (Position), and one from ?map_error (Error). The user will see all three labels.


?Locus Location ?Chromosome #map_location

?map_location Position Float #map_error

?map_error Error Float

Locus : xyz
Location VIII Position 10.0 Error 0.2
Location IX Position 57.0 Error 0.25

Position in model

Constructed type grafts must be onto the tip of a branch; that is, you cannot splice the extension into the middle of a series of fields or labels:

         Composition  ?Country #Components Int//***WRONG***
The "tip of the branch" rule holds when you nest a constructed type to a constructed type, as in the ?Locus/?map_location/?map_error example above.

XREF owners and targets

Because the same constructed type can appear in different classes, certain limitations exist on their use. Consider the class definitions

?TShirt Composition #Components

?Components Dye Text ?Manufacturer XREF TShirt

?Manufacturer TShirt ?TShirt
and the data

TShirt : sam99
Composition Dye Blue-12 Monsanto
From what you have learned about XREF, you would predict that the XREF in ?Components would direct a Component object to send its name to a Manufacturer object, filling out the field following the TShirt label in the Manufacturer. But something seems to be wrong: the target is expecting a TShirt, not a Component!

As it turns out, constructed types take their identity from the object that invokes it (in this case a TShirt). Thus what the Component object forwards is not the name of a Component but rather sam99. Thus if you examine the result of entering the sam99 data, you will see the following:

Because a constructed type containing an XREF transmits the name of the invoking object, there is a limit on the extent to which you can reuse the constructed type in your models. Without an XREF, a constructed type can be used in many different classes:

?Components Dye Text ?Manufacturer

?TShirt Components #Components

?Shoes Made_of #Components

?Junk_Food Contains #Components
But the presence of an XREF means that an object name will be sent to a target field--and that target field can contain only objects from a single class. Thus if you have

?Components Dye Text ?Manufacturer XREF TShirt

?Manufacturer TShirt ?TShirt

?TShirt Components #Components

?Junk_Food Contains #Components
you cannot invoke the constructed type from anything other than a TShirt; you will not be able to enter data like this:

Junk_Food : "Jelly Beans"
Contains Dye Red-2 DuPont
ACEDB will attempt to insert a Junk_Food object into the ?TShirt field in the Manufacturer--an error.

Another limitation is that you cannot set up a symmetrical XREF if a constructed type acts as an intermediate. You cannot target a constructed type:

?TShirt Composition #Components

?Components Dye ?Manufacturer XREF TShirt

?Manufacturer TShirt XREF Dye //**WRONG**
Nor will this attempt to chain XREFs work:

?TShirt Composition #Components
        Manufacturer ?Manufacturer

?Components Dye ?Manufacturer XREF TShirt

?Manufacturer TShirt XREF Manufacturer

Show me the whole t-shirt model again.

Back to Table of Contents