xsharp.eu • Q re variable scope
Page 1 of 1

Q re variable scope

Posted: Mon Sep 11, 2023 9:44 pm
by RolWil
Hello everyone,

I have a question re variable scope.

The system I’m converting was written in the Harbour/Clipper dialect and that's what I'm using in the X# conversion.

I have over 100 variables declared as ‘PUBLIC’ in the top (controlling) module (let’s call it ‘TOP.PRG’). These are all ‘set’ at that level before any of the dozens of other modules (let’s call them ‘MOD1.PRG’, ‘MOD2.PRG’, ‘MODn.PRG …) are called.

How can I best declare these variables so they are ‘visible’ by the called modules? For example, I have a public var that tracks the user’s preferred language and which is set at the very beginning (TOP.PRG) based on the user’s login. The var is referenced by just about every called module (MODn.PRG).

EDIT: the variables should not only be visible my the called modules, but also modifiable. For example, MOD3.PRG should be able to change the preferred language variable in a global way.

As always, thanks for your help.

Roland

Re: Q re variable scope

Posted: Mon Sep 11, 2023 11:35 pm
by RolWil
I just thought of something: s a class using get() set() methods the best option?

Re: Q re variable scope

Posted: Tue Sep 12, 2023 3:57 am
by wriedmann
Hi Roland,
in a pure .NET way you can use a singleton object.
Please look at this code:

Code: Select all

class ValStorage
static protect initonly _oCurrent as ValStorage
protect _cMyVar1 as string
static constructor()
_oCurrent := ValStorage{}
return
protected constructor()
_cMyVar := "Roland" //Initialization
return
static property MyVar1 as string get _oCurrent:_cMyVar1 set _oCurrent:_cMyVar1 := value
end classe
And then you can read and write to this variable like this

Code: Select all

ValStorage.MyVar1 := "not Roland"
If you need explanations how this works, please let me know.
Wolfgang
P.S. I hope to no have any typing errors. I use classes like these in all my X# applications

Re: Q re variable scope

Posted: Tue Sep 12, 2023 5:51 am
by robert
Roland,
A simple but effective solution is also to use global variables. These become static members of the compiler generated function class.
You can control their visibility like this:

Code: Select all

INTERNAL GLOBAL Foo AS STRING // visible everywhere in the current assembly
PUBLIC GLOBAL Bar AS INT     // Also visible in code that references the assembly
STATIC GLOBAL FooBar as LOGIC  // Only visible in the current module
Typing of the GLOBAL is optional, but recommended. You can always type the global as OBJECT or USUAL if the global may hold more than one type.


Robert

Re: Q re variable scope

Posted: Tue Sep 12, 2023 7:30 am
by Chris
Hi Roland,

Another note, just in case you are not aware, PUBLICs and PRIVATEs are also supported in X#, and you can still use them like you did in Harbour/Clipper/VO, you just need to enable the related compiler option for them (/memvar), which you can find in the compiler page of the app properties.

So this option is still there for compatibility (and making it easier to port existing code more easily), but of course it's indeed a lot better if you replace them with strongly typed GLOBALs or a singleton class as the guys already suggested.

Re: Q re variable scope

Posted: Tue Sep 12, 2023 9:47 pm
by RolWil
thanks for the quick help folks!

Tested with PUBLIC GLOBAL and all is good.

Cheers
Roland