Where should I instantiate a global object?

I feel a bit of a cheat: I’m not exactly new to coding, or Xojo, or even the concept of OOP. But I’m making slow headway. My earliest coding was BASIC on a ZX81, more recently using Visual Basic 6. I struggled a bit with Visual Studio, and the change of framework. Then I went all Apple, and adopted REAL Basic/Real Studio/Xojo. For a number of reasons, I seem to be able to get only so far with any of the applications which I’ve tried/am trying to develop.

I’m currently having difficulty getting my head around the creation/declaration/use of Classes/objects. In one app. I’ve been using Modules for a number of purposes, eg a Module with a Method to display a MessageBox which varies depending on how it’s called. I see no reason to change that. But in another case, it makes more sense to create a Class. I’ve done that, but then I’ve hit a snag: Where do I instantiate it? If I create a new instance in the MainWindow, it is hidden from any other window, e.g. a preferences dialog, which I open. I’ve tried instantiating it in the Open event of the App itself, to no avail. The program throws up its hands in horror at yet another NilObjectException.

While I should have expected instantiating the Object in the Open Event of the App to have made it visible and available to the rest of the application, what I did eventually was to create the variable within a Module, then Instantiate the Object in the Open Event of MainWindow.

Can anyone help me to understand why creating the object in a module works, but not in the App? Or does it??

Its all a matter of SCOPE
anything instantiated in a window is local to that window
anything instantiated in a method is local to that method
anything instatiated in a module can be either GLOBAL or PRIVATE (there is more but for another day)

Global is just that… available to any other part of your app, Private would be local to that module (and its methods)

“APP” is not the entier application, but simply another class (albeit a special one)

It does work inside the app object too. It might at times be hard to tell the order of events, so when you encounter a NilObject exception when accessing the app-level object that should be instantiated during app.open, the open event handler did not progress that far yet.

A way to avoid these troubles would be to use lazy initializing: Create, like in the app object, a property of the class kind and make it a computed property. Remove the setter, and inside the getter, insert a Nil check first which does the initialization of the protected “real” property, then return it. This way you can be sure the property will always be initialized during its first use.

an object in the APP scope, is NOT global without the addition of the namespace indicator

in APP

DT as DATE

App.OPEN

dt=new date

that is all well and good for any code inside APP class

window.open

msgbox dt.shortdate // This doesn't work
msgbox app.dt.shortdate // this does

Objects in APP can be PUBLIC or PRIVATE (protected is another discussion)
Objects in a MODULE can be GLOBAL or PRIVATE

public requires a namespace designator, global does not

Full agreement of course. While we’re at it, real global properties are things to avoid preferably. Most properties are much better kept inside their custom name space (which can be the app object if applicable, or a module, or class …).

If you must, the simplest thing to do is to create a module, name it “Globals” (note the plural nature since “Global” is a reserved word) and only add elements into it that have Public/Global scope. That keeps things straight as you continue with your coding or revisit an old project.

It sounds like it’s not a matter of where you instantiate it, but how. In your module, you should have a property of your class type.

Preferences as PreferenceClass

When you instantiate it, simply put

Preferences = New PreferenceClass

A common error is to do

[code]
dim Preferences as PreferenceClass
Preferences = New PreferenceClass

[code]
This creates a local variable that shadows the global one. The local variable get set, leaving the global one nil.

1 Like

+1 :slight_smile:

Oh my. Me too.
Christmas. Black and white portable television. Cassette tape deck.
And this baby…

DIzzy days. :slight_smile:

You guys were posh having a ZX81, I had a ZX80 that you had to build before you could even use it!!!

We’re roving waaaay off topic, but …

I assembled 11 of Sir Clive’s little kits for others on board my ship back in the day. Bythe third, I could do it with my eyes closed (almost).

[quote=445324:@Nicholas KERR]
Can anyone help me to understand why creating the object in a module works, but not in the App? Or does it??[/quote]
my initial reply to this thread was going to be “you shouldnt” … ever :stuck_out_tongue:

The reason it doesnt work when you have the property defined on App is a bunch of issues all rolled into one (like App is actually a method call NOT a class instance but …)
The instance the App method returns is a SINGLETON - only one exists for the entire running application
The Xojo runtime creates it and initializes it a part of starting up your app
And when you add a property to it you cannot make it “global” - its a property of a class and those cannot be global

A module on the other hand has NO such need to be “created” at any time
It can have methods, and many other things like enumerations, properties, etc that ARE truly global

BUT I would caution against creating lots of globals

IF you find you need to I would take Tim’s advice & create a module called globals and put anything global in there that you think you need to be global.
But keep this thing small with very few true globals

Vielen Dank für dies. The query arose precisely because I was trying to avoid the use of a Global Module.

[quote=445418:@Norman Palardy]my initial reply to this thread was going to be “you shouldnt” … ever :stuck_out_tongue:

The reason it doesnt work when you have the property defined on App is a bunch of issues all rolled into one (like App is actually a method call NOT a class instance but …)
The instance the App method returns is a SINGLETON - only one exists for the entire running application
The Xojo runtime creates it and initializes it a part of starting up your app
And when you add a property to it you cannot make it “global” - its a property of a class and those cannot be global

A module on the other hand has NO such need to be “created” at any time
It can have methods, and many other things like enumerations, properties, etc that ARE truly global

BUT I would caution against creating lots of globals

IF you find you need to I would take Tim’s advice & create a module called globals and put anything global in there that you think you need to be global.
But keep this thing small with very few true globals[/quote]
So, back to the Globals Module it is!
Thanks, all.
¡Hasta la próxima!

[quote=445362:@Tim Hare]It sounds like it’s not a matter of where you instantiate it, but how. In your module, you should have a property of your class type.

Preferences as PreferenceClass

When you instantiate it, simply put

Preferences = New PreferenceClass

A common error is to do

[code]
dim Preferences as PreferenceClass
Preferences = New PreferenceClass

[code]
This creates a local variable that shadows the global one. The local variable get set, leaving the global one nil.[/quote]

Yes! Thanks. I keep making this fundamental (I nearly wrote ‘basic’) error. Having created the class, and then included it as a property of a module, I try to instantiate it in the open event of the App. With the inevitable result. Only when I declare a new instance of the existing object does it come right.
Since I want only a SINGLETON (thank you for that), it satisfies my requirements to instantiate the objects in the open event of the app.

I’m now scratching my ear over something else. But I’ll address that in another convo.