Assignment for objects and structures

In PowerBuilder, assignment for objects is different from assignment for structures or autoinstantiated objects:

  • When you assign one structure to another, the whole structure is copied so that there are two copies of the structure.

  • When you assign one object variable to another, the object reference is copied so that both variables point to the same object. There is only one copy of the object.

Events

Assignment for structures

Declaring a structure variable creates an instance of that structure:

str_emp_data str_emp1, str_emp2 // Two structure instances

When you assign a structure to another structure, the whole structure is copied and a second copy of the structure data exists:

str_emp1 = str_emp2

The assignment copies the whole structure from one structure variable to the other. Each variable is a separate instance of the structure str_emp_data.

Restriction on assignment

If the structures have different definitions, you cannot assign one to another, even if they have the same set of variable definitions.

For example, this assignment is not allowed:

str_emp str_person1
str_cust str_person2
str_person2 = str_person1 // Not allowed

For information about passing structures as function arguments, see Passing arguments to functions and events.

Assignment for objects

Declaring an object variable declares an object reference:

uo_emp_data uo_emp1, uo_emp2 // Two object references

Using the CREATE statement creates an instance of the object:

uo_emp1 = CREATE uo_emp_data

When you assign one object variable to another, a reference to the object instance is copied. Only one copy of the object exists:

uo_emp2 = uo_emp1 // Both point to same object instance

Ancestor and descendant objects

 Assignments between ancestor and descendant objects occur in the same way, with an object reference being copied to the target object.

Suppose that uo_emp_data is an ancestor user object of uo_emp_active and uo_emp_inactive.

Declare variables of the ancestor type:

uo_emp_data uo_emp1, uo_emp2

Create an instance of the descendant and store the reference in the ancestor variable:

uo_emp1 = CREATE USING "uo_emp_active"

Assigning uo_emp1 to uo_emp2 makes both variables refer to one object that is an instance of the descendant uo_emp_active:

uo_emp2 = uo_emp1

For information about passing objects as function arguments, see Passing arguments to functions and events.

Assignment for autoinstantiated user objects

Declaring an autoinstantiated user object creates an instance of that object (just like a structure). The CREATE statement is not allowed for objects with the Autoinstantiate setting. In the following example, uo_emp_data has the Autoinstantiate setting:

uo_emp_data uo_emp1, uo_emp2 // Two object instances

When you assign an autoinstantiated object to another autoinstantiated object, the whole object is copied to the second variable:

uo_emp1 = uo_emp2

You never have multiple references to an autoinstantiated user object.

Passing to a function

When you pass an autoinstantiated user object to a function, it behaves like a structure:

  • Passing by value passes a copy of the object.

  • Passing by reference passes a pointer to the object variable, just as for any standard datatype.

  • Passing as read-only passes a copy of the object but that copy cannot be modified.

Restrictions for copying

Assignments are allowed between autoinstantiated user objects only if the object types match or if the target is a nonautoinstantiated ancestor.

Rule 1

If you assign one autoinstantiated object to another, they must be of the same type.

Rule 2

If you assign an autoinstantiated descendant object to an ancestor variable, the ancestor cannot have the Autoinstantiate setting. The ancestor variable will contain a reference to a copy of its descendant.

Rule 3

If you assign an ancestor object to a descendant variable, the ancestor must contain an instance of the descendant or an execution error occurs.

Examples

To illustrate, suppose you have these declarations. Uo_emp_active and uo_emp_inactive are autoinstantiated objects that are descendants of non-autoinstantiated uo_emp_data:

uo_emp_data uo_emp1 // Ancestor
uo_emp_active uo_empa, uo_empb // Descendants
uo_emp_inactive uo_empi // Another descendant

Example of rule 1

When assigning one instance to another from the user objects declared above, some assignments are not allowed by the compiler:

uo_empb = uo_empa // Allowed, same type
uo_empa = uo_empi // Not allowed, different types

Example of rule 2

After this assignment, uo_emp1 contains a copy of the descendant object uo_empa. Uo_emp_data (the type for uo_emp1) must not be autoinstantiated. Otherwise, the assignment violates rule 1. If uo_emp1 is autoinstantiated, a compiler error occurs:

uo_emp1 = uo_empa

Example of rule 3

This assignment is only allowed if uo_emp1 contains an instance of its descendant uo_empa, which it would if the previous assignment had occurred before this one:

uo_empa = uo_emp1

If it did not contain an instance of target descendant type, an execution error would occur.

For more information about passing arguments to functions and events, see Passing arguments to functions and events.