Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Singleton Class in Visual FoxPro 9.0 1

Status
Not open for further replies.

Irwin1985

Programmer
Feb 2, 2017
44
ES
I need to create my own Singleton Class using Visual FoxPro 9.0
I tried this:
[pre]
oRef1 = CreateObject("Singleton")
oRef2 = CreateObject("Singleton")
oRef1.cTest = "Some Text"

?oRef1.cTest && Some Text
?oRef2.cTest && Prints nothing :(
Release oRef1, oRef2
Clear All
Return

*-- Singleton class
Define Class Singleton As Custom
cTest = ""
Procedire Init
If Type("This.Ref") = "U"
This.AddProperty("Ref", THIS)
Endif
Return This.Ref
Endproc
Enddefine
[/pre]
I can't get the same instance. Any help?
Thanks a lot!
 
The only real way to have a VFP singleton is as OLE Public class set to Multi Use.

While Init is the event triggered by CreateObject, its return value is not overriding the reference you get back into oRef1, oRef2, or whatever. Foxpro has no such concept as its init isn't a constructor. "This" is already referring to the new instance of the class and so Init already is the aftermath of the construction of an object.

I find this idea based on THIS_ACCESS: [URL unfurl="true"]http://www.victorespina.com.ve/wiki/index.php?title=SingletonPattern_(VFP)[/url]

Before looking at that it's worth learning how THIS_ACCESS works as a special access method for an object itself. Unlike the property_access methods you can generate when defining a new member (property) of a class, this is for the object itself and gets invoked from access to any member with the member name as parameter. You get standard behavior when returning THIS from THIS_Access (notice you don't return THIS.&cMember) and that's used here to let access to any instance be redirected to a central instance. Also note, this isn't only working for property members, also for methods and events. Redirecting to another object the call to methods also is redirected - using the same parameterization as the original call to THIS was using.

The first instantiation already creates a second object stored as _SCREEN child object and any access to members (except a few methods and properties) is then redirected to this _SCREEN child object. I'd perhaps change this so the first instantiation puts itself (THIS) to a _SCREEN property instead of creating another instance of its class.

The downside of that is, that the THIS_ACCESS method doesn't work with OLE public classes. But then we have Multi Use instantiation for OLE classes.

In a way, this is okay, as OLE class usage always is slower than native class usage. But if you even look for a singleton spanning multiple VFP processes (eg preventing multiple starts of an application) the Multi Use OLE mechanism works that way and there are solutions using some kind of mutex: faq184-1767

PS: You can also find about other instances with AINSTANCE(), but this function only sees instances in variables and (what's not documented) only in variables in scope. I tried putting AINSTANCE into the init so the class init puts a reference to the first instance into a property, but that won't see previous instances stored in local variables, for example, so AINSTANCE() is of limited use.

Bye, Olaf.

Olaf Doschke Software Engineering
 
And just a few remarks.

What you tried with "This.Ref" would only work, if the singleton would be a static class, but VFP lacks that concept overall, we just have public (by default), private and protected classes or members and even these concepts are flawed in some cases. This.Ref already is the Ref property of a separate new instance in your code, so that won't work. You can't set the Ref property to be a static member.

I just had another idea, which kind of works, but not with the object itself:

Code:
Clear
oRef1 = CreateObject('singletonproperty')
? oRef1.cFirstInstanceSys2015 
? oRef1.nFirstInstanciationTime 

oRef2 = CreateObject('singletonproperty')
? oRef2.cFirstInstanceSys2015 
? oRef2.nFirstInstanciationTime 

* only releasing all instances and clearing the class definition from memory you get a new evalutaion of cFirstInstanceSys2015 and nFirstInstanciationTime.
Store null to oRef1, oRef2
Clear Class singletonproperty

oRef3 = CreateObject('singletonproperty')
? oRef3.cFirstInstanceSys2015 
? oRef3.nFirstInstanciationTime 

Define Class singletonproperty as Custom 
   cFirstInstanceSys2015 = Sys(2015)
   nFirstInstanciationTime = Seconds()
EndDefine

If you could define a property oSingleton = THIS, that only would be evaluated in the first instantiation and every other instance of the class would have a reference to the first instance, but VFP doesn't allow referencing THIS in such initializing values of class properties. If this would work, you'd need a THIS_ACCESS method returning THIS.oSingleton. Well, aside of the fact ideally you wouldn't even have further instances. But that's only possible with Multi Use instantiation of OLE classes, that's why I initially said it's the only real way.

The implementation of Victor Espina also doesn't prevent multiple instances, all instances just redirect their own usage to an instance created as _SCREEN property. That's why this only works for classes you can put into a property and the class definition better is a flat class, no object properties like controls on a form. They do work, that's not the reason I say better a flat clas, access to any of the child object goes through the topmost object THIS_ACCESS and childobjects don't need their own THIS_ACCESS method at all, but the more complex a class is with all its child objects, the more memory you still allocate, the more init code and anything done in it like data binding queries still runs. Only all usage of the additional instances after their init is redirected to the initial instance.

Bye, Olaf.

Olaf Doschke Software Engineering
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top