Unassigned variable

Hello All,

I have a written a very basic script to populate create a DB with text and choice DBE's. The Dialog Box is populating and displaying correctly but when updating the module attributes, an unassigned variable dxl error is displayed for each of the attributes being assigned.

I have written many scripts similar to this in the past but this has me baffled. Can anyone please point out the error of my ways?
 

string disp[]    = {}
        string cav[]    ={}
        string disp_attr         = "Test Data Disposal"
        string caveat_attr       = "Caveat"
                        
        DB  setUpTest           = create("Set Test attributes", styleFixed|styleCentered|styleFloating)
        full setUpTest
        DBE testName            = field (setUpTest,"Test Title","Enter test title here",20,true)
        full setUpTest  
        DBE testDesc            = field (setUpTest,"Test Description","Enter test description here",20,true)
        full setUpTest
        DBE env                         = field (setUpTest,"Test Environment","Enter test environment here",20,false)
        full setUpTest
        DBE dataSec                     = choice (setUpTest,"Data Classification",cav,4,20,false)
        full setUpTest
        DBE custodian           = field (setUpTest,"Data Custodian","Enter data custodian here",20,false)
        full setUpTest
        DBE format                      = field (setUpTest,"Data Format","Enter data format here",20,false)
        full setUpTest
        DBE disposal            = choice (setUpTest,"Data Disposal",disp,2,20,false)
        
        string testenv = get(env)
        string cust = get(custodian)
        string sec = get(dataSec)
        string dataformat = get(format)
        string d = get(disposal)
                
        void setData (DBE db)
        {
                Module m = current
                
                m."Test Environment" = testenv
                m."Test Data Disposal" = d
                m."Data Format" = dataformat
                m."Custodian" = cust
                m."Caveat" = sec
                save(m)
        }
                
        DBE SubBut      = button(setUpTest,"Submit",setData)
        
        realize (setUpTest)
        
        
        void getCaveat(Module m)
        {
                AttrDef ad = find (m,caveat_attr)
                if (!null ad)
                {
                        AttrType at = ad.type
                        if(!null at && at.type == attrEnumeration)
                        {
                                string cavStrings[at.size]
                                int i = 0
                                for (i = 0; i < at.size; i++) 
                                cavStrings[i] = at.strings[i]
                        set(dataSec,cavStrings)
                }
            else
            {
                        errorBox ("Attribute >"caveat_attr"<is not an enumeration!")
            }
        }
        else
        {
                errorBox ("Could not find attribute >"caveat_attr"< in module >" (fullName m)"<!")
        }
        }
        
        void getDisp(Module m)
        {
                AttrDef ad = find (m,disp_attr)
                if (!null ad)
                {
                        AttrType at = ad.type
                        if(!null at && at.type == attrEnumeration)
                        {
                                string szStrings[at.size]
                                int i = 0
                                for (i = 0; i < at.size; i++) 
                                szStrings[i] = at.strings[i]
                        set(disposal,szStrings)
                }
            else
            {
                        errorBox ("Attribute >"disp_attr"<is not an enumeration!")
            }
        }
        else
        {
                errorBox ("Could not find attribute >"disp_attr"< in module >" (fullName m)"<!")
        }
        }
        
        getCaveat (current)
        getDisp(current)

 


Thanks

Mark

 


mwilliamson - Tue Feb 03 10:18:38 EST 2009

Re: Unassigned variable
llandale - Tue Feb 03 11:33:36 EST 2009

It would help if you specified which line was getting the unassigned variable reference.

[] Anyway, you fail to show the dialog after realizing it and changing its values; add 'show(setUpTest)' at the bottom.

On other news:
[] at about line 22 you are defining variables and retrieving their values from a dialog box elements whose dialog box does not yet exist. These 'get' commands should follow the 'realize' command. In this case, these variables are never re-initialized; so you can realistically put them at the top of the DXL and assign them constant values, and refer to the variables when defining the DBEs. Or, in this case, just delete the variables since they are never actually used. It seems to me, however, that you may want to 'get' the values from the elements INSIDE the callback which uses them, in this case 'setData()'.

[] You should make sure the attributes in question are defined for the module:
http://if (!ad.module) then flip off the user

' array, sadly, needs to be a global variable. The variable used when initialzing a Choice DBE is referenced, not when 'set', but rather when 'realize'd and 'show'n. That is, if you [szStrings[0] = "A"; set(disposal,szStrings); szString, you will see "B" not "A".

In your case, at the bottom when your show the dialog, variable szStrings no longer actually exists (since its inside a function that has exited) and you get whatever garbage is in the location now. Ditto for 'cavStrings[]'. It may be best to define these variables very big, and use
[set(DBE choice, string choices ],int noOfChoices) perm when setting the DBE.

[] You should routinely define a global variable with the 'current' module when the DXL starts, and refer to that variable when you need to. Defining Module m = current inside your setData() function is a recipe for disaster, as the 'current' module may change. Instead, put Module mCurr = current() at the top and have setData() use 'mCurr'.

[] Notice the clumsiness in the layout of the DXL and how hard it is to read and follow; that's because of the need to have many DB and DBE variables and callback functions refer to each other. It works out far better to structure such DXL like this:
> Define global variables, initialize many of them. Module mCurr = current() is routine.
> Define your DB and DBE variables without initializing them
> Define the various functions of your script.
> Define the callback functions of your script; these will often 'get' current values of the various DBEs.
> Define function 'MakeTheDialog()' that creates the DB and DBEs, and realizes and shows the dialog.
> at the bottom, have a comment [//**** BEGIN MAIN ****]; then invoke MakeTheDialog().

> Louie

Re: Unassigned variable
llandale - Tue Feb 03 11:39:25 EST 2009

llandale - Tue Feb 03 11:33:36 EST 2009
It would help if you specified which line was getting the unassigned variable reference.

[] Anyway, you fail to show the dialog after realizing it and changing its values; add 'show(setUpTest)' at the bottom.

On other news:
[] at about line 22 you are defining variables and retrieving their values from a dialog box elements whose dialog box does not yet exist. These 'get' commands should follow the 'realize' command. In this case, these variables are never re-initialized; so you can realistically put them at the top of the DXL and assign them constant values, and refer to the variables when defining the DBEs. Or, in this case, just delete the variables since they are never actually used. It seems to me, however, that you may want to 'get' the values from the elements INSIDE the callback which uses them, in this case 'setData()'.

[] You should make sure the attributes in question are defined for the module:
http://if (!ad.module) then flip off the user

' array, sadly, needs to be a global variable. The variable used when initialzing a Choice DBE is referenced, not when 'set', but rather when 'realize'd and 'show'n. That is, if you [szStrings[0] = "A"; set(disposal,szStrings); szString, you will see "B" not "A".

In your case, at the bottom when your show the dialog, variable szStrings no longer actually exists (since its inside a function that has exited) and you get whatever garbage is in the location now. Ditto for 'cavStrings[]'. It may be best to define these variables very big, and use
[set(DBE choice, string choices ],int noOfChoices) perm when setting the DBE.

[] You should routinely define a global variable with the 'current' module when the DXL starts, and refer to that variable when you need to. Defining Module m = current inside your setData() function is a recipe for disaster, as the 'current' module may change. Instead, put Module mCurr = current() at the top and have setData() use 'mCurr'.

[] Notice the clumsiness in the layout of the DXL and how hard it is to read and follow; that's because of the need to have many DB and DBE variables and callback functions refer to each other. It works out far better to structure such DXL like this:
> Define global variables, initialize many of them. Module mCurr = current() is routine.
> Define your DB and DBE variables without initializing them
> Define the various functions of your script.
> Define the callback functions of your script; these will often 'get' current values of the various DBEs.
> Define function 'MakeTheDialog()' that creates the DB and DBEs, and realizes and shows the dialog.
> at the bottom, have a comment [//**** BEGIN MAIN ****]; then invoke MakeTheDialog().

> Louie

Doh! Put my suggested DXL inside brackets, which is interpreted as Hyperlinks. Guess that is 'fubar' ..err.. 'foo@bar.com'.

Re: Unassigned variable
mwilliamson - Tue Feb 03 12:01:26 EST 2009

llandale - Tue Feb 03 11:33:36 EST 2009
It would help if you specified which line was getting the unassigned variable reference.

[] Anyway, you fail to show the dialog after realizing it and changing its values; add 'show(setUpTest)' at the bottom.

On other news:
[] at about line 22 you are defining variables and retrieving their values from a dialog box elements whose dialog box does not yet exist. These 'get' commands should follow the 'realize' command. In this case, these variables are never re-initialized; so you can realistically put them at the top of the DXL and assign them constant values, and refer to the variables when defining the DBEs. Or, in this case, just delete the variables since they are never actually used. It seems to me, however, that you may want to 'get' the values from the elements INSIDE the callback which uses them, in this case 'setData()'.

[] You should make sure the attributes in question are defined for the module:
http://if (!ad.module) then flip off the user

' array, sadly, needs to be a global variable. The variable used when initialzing a Choice DBE is referenced, not when 'set', but rather when 'realize'd and 'show'n. That is, if you [szStrings[0] = "A"; set(disposal,szStrings); szString, you will see "B" not "A".

In your case, at the bottom when your show the dialog, variable szStrings no longer actually exists (since its inside a function that has exited) and you get whatever garbage is in the location now. Ditto for 'cavStrings[]'. It may be best to define these variables very big, and use
[set(DBE choice, string choices ],int noOfChoices) perm when setting the DBE.

[] You should routinely define a global variable with the 'current' module when the DXL starts, and refer to that variable when you need to. Defining Module m = current inside your setData() function is a recipe for disaster, as the 'current' module may change. Instead, put Module mCurr = current() at the top and have setData() use 'mCurr'.

[] Notice the clumsiness in the layout of the DXL and how hard it is to read and follow; that's because of the need to have many DB and DBE variables and callback functions refer to each other. It works out far better to structure such DXL like this:
> Define global variables, initialize many of them. Module mCurr = current() is routine.
> Define your DB and DBE variables without initializing them
> Define the various functions of your script.
> Define the callback functions of your script; these will often 'get' current values of the various DBEs.
> Define function 'MakeTheDialog()' that creates the DB and DBEs, and realizes and shows the dialog.
> at the bottom, have a comment [//**** BEGIN MAIN ****]; then invoke MakeTheDialog().

> Louie

Hi Louie,

Thanks for your excellent response, I now have all the constituent elements back where they were 5 hours ago and all is working perfectly. I think the missing statement was the additional "show" following realization. Your advice on structure is well noted as often my dxl is confusing to follow and debug accordingly. Unfortunately the Telelogic DXL course I attended did not particularly consider code structure. My initial dxl script has mushroomed to almost 3000 lines of code.

I am populating szStrings from the enumerated list within the specified attribute so am unsure as to your issue with the initial array declaration.

Many thanks again

Mark

ps Can we have the old forum back?

Re: Unassigned variable
llandale - Mon Feb 23 16:47:27 EST 2009

mwilliamson - Tue Feb 03 12:01:26 EST 2009
Hi Louie,

Thanks for your excellent response, I now have all the constituent elements back where they were 5 hours ago and all is working perfectly. I think the missing statement was the additional "show" following realization. Your advice on structure is well noted as often my dxl is confusing to follow and debug accordingly. Unfortunately the Telelogic DXL course I attended did not particularly consider code structure. My initial dxl script has mushroomed to almost 3000 lines of code.

I am populating szStrings from the enumerated list within the specified attribute so am unsure as to your issue with the initial array declaration.

Many thanks again

Mark

ps Can we have the old forum back?

Back.

The 'set' command is used when the dialog is 'realized' or 'shown', its NOT used when the 'set' command is issued. That is, the array used in the Set command is referenced during 'realize'. Since that array is defined inside a function which has exited when 'realize' is issued, the array doesn't actually exist anymore and you will get whatever garbage is in that stack location. Put another way, the 'set' command could mean 'When realizing my dialog, use this array to initialize my list element'.

It doesn't matter where you get the data for your array, it pretty much must be defined in the same context as the Realize. That almost always means you have to define it globally. Since you may not know how many elements you will need, you might declare that array very large, then polulate it with some enumerated attr values, then send the 'set' command the number of enumerated values the array actually has.

Does that help?

  • Louie