Question:

How can I set an ASNA Visual RPG for .NET data structure to *Nothing (so that it goes out of memory)? My tests show that after I use the Clear operation code against a data structure that it is still in memory.

Answer:

A Visual RPG for .NET (AVR) data structure is a static structure owned by the class in which it is defined. The data structure is faithful to green RPG data structure idioms. That is, its values persist until its owner goes out of scope. In .NET that means when its owning class goes out of scope; in green RPG that means when the RPG's LR indicator is set on and the RPG program ends.

Let's consider an example. This example shows a very small data structure. Structures like this can get huge in production work.

BegClass TestCase
    DclDs CustomerData FldScope(*Global) 
        DclDsFld Name Type(*Char) Len(40) 
        DclDsFld Address Type(*Char) Len(40) 
        DclDsFld City Type(*Char) Len(30) 
        DclDsFld State Type(*Char) Len(2) 


    BegSr Run Access(*Public) 
        CustomerData.Name = 'Neil Young'
        CustomerData.Address = 'Broken Arrow Ranch'
        CustomerData.City = 'Costa Mesa'
        CustomerData.State = 'CA'

        ...

        Clear CustomerData
    EndSr
EndSr

Figure 1. A typical AVR data structure

Figure 1 above defines a data structure named CustomerData that defines four fields: Name, Address, City, and State. Here are some facts about AVR data structures:

  • They only support green-screen RPG primitive data types (ie, *Packed, *Char, *Date, etc). You cannot define fields with .NET data types (ie, *String (or System.String), or System.Data.DataSet, etc).
  • Issuing the Clear opcode sets character values to blanks and numeric values to 0. Note that a *Char Len(40) field set to blanks takes up the same 40 bytes of memory as a does a *Char Len(40) with a value assigned to it (ie, blanks are values!).
  • You cannot pass data structures as arguments to other functions or subroutines.
  • Data structures declared with FldScope(*Global) (which is the default), require accessing data structure fields with fully qualified names (ie, datasstructurename.fieldname).
  • Data structures declared with FldScope(*Local) require accessing data structure fields with the data structure field name only.

Using classes as a data structure alternative

AVR data structures have some specific use cases where they are very necessary. Two examples are defining externally described data structures and using them as parameters for IBM i program calls. Often, though, there are better ways to store data in memory in AVR for .NET. One good way to is to create a class.

The class below defines an alternative to the data structure defined in Figure 1:

BegClass CustomerData
    DclProp Name Type(*Char) Len(40) Access(*Public) 
    DclProp Address Type(*Char) Len(40) Access(*Public) 
    DclProp City Type(*Char) Len(30)  Access(*Public) 
    DclProp State Type(*Char) Len(2)  Access(*Public)               
EndClass

Figure 2a. A class that replaces the data structure in Figure 1.

To use the CustomerData class,

BegClass TestCase
    DclFld cd Type(CustomerData) New()

    BegSr Run Access(*Public) 
        cd.Name = 'Neil Young'
        cd.Address = 'Broken Arrow Ranch'
        cd.City = 'Costa Mesa'
        cd.State = 'CA'

        ...

        cd = *Nothing             
    EndSr

Figure 2b. An example using the CustomerData class.

Using a class for data like this has several advantages over a data structure:

  • You can set it to *Nothing (which causes the garbage collector to suck it out of memory).
  • You can pass it as an argument to functions and subroutines.
  • Class properties can be any .NET or AVR data type.
  • A property in a class can reference an instance of another class--which lets you model complex data structures effectively.
  • You can easily instance more than one copy of a data class (for example, you might want one to refer to "before update" data and one to refer to "after update" data)
  • Classes can have actions (methods). See Figure 2c below for an example.

The class below offers a Clear method to clear an instance of the class's properties (this doesn't set them to *Nothing, it simply clears there values).

BegClass CustomerData
    DclProp Name Type(*Char) Len(40) Access(*Public) 
    DclProp Address Type(*Char) Len(40) Access(*Public) 
    DclProp City Type(*Char) Len(30)  Access(*Public) 
    DclProp State Type(*Char) Len(2)  Access(*Public)               

    BegSr Clear Access(*Public) 
        Clear Name
        Clear Address
        Clear City 
        Clear State 
    EndSr 
EndClass

Once you start using classes for simple data purposes like this, you'll quickly find yourself stretching the concept dramatically. The next thing you know you'll be declaring disk files in them and making sophisticated data access classes.