Static variables behave differently depending on type

Posted by thomass@proventus.no on 08-Jun-2010 08:13

I've come accross a thing i the OOABL when using static variables and methods inside a class. It seems static variables is behaving differently when it is holding an object of a class type, then when it's a simple type like int.

Example:

<code>

USING Progress.Lang.*.

CLASS TheStatic:

    def static var v_ctr as int init 0 no-undo.           
    def static var v_obj as class Container no-undo.   
   
    method public static void Increase():
        v_ctr = v_ctr + 1.   
       
        if not valid-object(v_obj) then do:
            v_obj = new Container().
        end.
        else do:
            v_obj:Increase().                  
        end.
    end.
   
    method public static int GetCurrentIntValue():
        return v_ctr.
    end.

    method public static int GetCurrentClassValue():
        return v_obj:GetCurrentValue().
    end.

    DESTRUCTOR TheStatic():
      MESSAGE "TheStatic:Destructor"
        VIEW-AS ALERT-BOX INFO BUTTONS OK.
    END.

END CLASS.

CLASS Container:
   
    def var v_ctr as int init 0 no-undo.
   
    constructor Container():
        v_ctr = 1.       
    end.
   
    method public void Increase():
        v_ctr = v_ctr + 1.
    end.
   
    method public int GetCurrentValue():
        return v_ctr.
    end.

    DESTRUCTOR Container():
      MESSAGE "Container:Destructor"
        VIEW-AS ALERT-BOX INFO BUTTONS OK.
    END.

END CLASS.

/* runner.p */

TheStatic:Increase().
TheStatic:Increase().
TheStatic:Increase().

/* Expecting 3 - 3*/

MESSAGE TheStatic:GetCurrentIntValue() " - " TheStatic:GetCurrentClassValue()
VIEW-AS ALERT-BOX.

</code>

When running this code (Runner.p) i in an editor I get the following result: 3 - 3 as expected.

However... When running it again I get the result 6 - 3. Again 9 - 3 and so forth. I would expect both numbers to increase by 3 every time.

An interesting point is that the Destuctor of the Conatiner-class is called after each run, this leads me to suspect that the garbage-collector is collecting the instance of the Container-class that is stored in the static variable even if the session has not ended (the editor is still running). The int variable however, is retaining its value between runs.

Am I misunderstanding something here?

[View:~/cfs-file.ashx/__key/communityserver-discussions-components-files/19/Container.cls.zip:550:0]

[View:~/cfs-file.ashx/__key/communityserver-discussions-components-files/19/Runner.p.zip:550:0]

[View:~/cfs-file.ashx/__key/communityserver-discussions-components-files/19/TheStatic.cls.zip:550:0]

All Replies

Posted by Peter Judge on 08-Jun-2010 08:39

If you're running this from the Procedure Editor (and I suspect you are), then there is some cleanup going on (done by the Proc Editor, not the GC) of the Contains object in v_obj. The relevant code is in adecomm/_runcode.p. Static object aren't GC'd anyway, since they live for the life of the session.

Are you trying to reproduce a larger issue, or is this something you've seen only from running in the Procedure Editor?

-- peter

Posted by thomass@proventus.no on 08-Jun-2010 09:15

Thanks, I've used this in a solution intended to run on an appserver, but was a bit hesitant when i couldn't get it to work in a procedure editor window. I tested the same code on an AppServer after your answer and it worked as expected there.

Is this a bug or a feature in the procedure editor "clean up" code? If there is no specific need for it to be there I would call this a bug, it certainly can make some confusion when developing classes with static members.

Posted by Peter Judge on 08-Jun-2010 09:39

Is this a bug or a feature in the procedure editor "clean up" code?

The cleanup is a feature; it comes from the Procedure Editor's attempt to provide a clean environment every time a procedure or class is run.

The documented fact is that once a static member is loaded, it stays loaded for the life of the session. The Procedure editor's run is just a subset of that lifespan, so I'd expect the static members to stay alive.

The only sure way is to have this code run in a separate session each time, when developing or testing. OE Architect makes it easier to set this up, with the Run Configurations (make sure to select the 'run in new AVM' option). OE Studio (aka AppBuilder and/or the Procedure Editor) don't.

If there is no specific need for it to be there I would call this a

bug, it certainly can make some confusion when developing classes

with static members.

Indeed it can. Especially when testing code, as in your case.

-- peter

This thread is closed