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 gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

how to know type of variable

Status
Not open for further replies.

Rishi ERP

Programmer
Oct 6, 2016
2
IN
There are 3 types of variables.
How can I come to know that particular variable is local, private or public?
 
If you work with best practices private and public variables should not exist and thus the question rather is for someone not programming in best practice ways.

Well, you have no varscope function, but LIST MEMORY tells you that scope type:
Code:
PUBLIC myvar1
LOCAL myvar2
myvar3="private"
LIST MEMORY LIKE myvar* TO scopes.txt noconsole
MODIFY file scopes.txt

I don't think there is a way to find out without routing that result to a file, maybe someone else may come up with something I don't know without further study of the help.

Even if you leave ground of best practices, i.e. when you know what you're doing, you should primarily know which scope your variables have yourself. Partly by programming with naming conventions, giving local variables l prefix, private variables p prefix and public (global) variables g prefix. Aside of the additional prefix t for (taken in) parameters, which can either be local or private depending on use of PARAMETERS or LPARAMETERS.

If you want to identify private variables because you want to throw errors or warnings in case someone tries to bleed in his variables into your code, causing side effects: a) your local vars will take precedence and their privates won't be modified,so if you declare all your variables LOCAL you are safe and b) you can END all private variables in scope via PRIVATE ALL. This means all names are reseverved for private variables you want to create in your code after that line, this does not define any private variables, it defines your private variable name space. You also make global vars inaccessible, see this demo:

Code:
PUBLIC goApp
goApp = CREATEOBJECT("empty")
Addproperty(goApp,"cAppname","my fine app")
? goApp.cAppName
somefunction()
FUNCTION somefunction()
   PRIVATE ALL
   ? goApp.cAppname && will error
   RETURN 42
ENDFUNC

Notice PRIVATE is not there to declare private variables, but define a name space. Also notice: This does not show a bug, this behaviour is by design. This also is no showing the evil side of PRIVATE scoping, it shows you could do [tt]PRIVATE ALL EXCEPT goApp[/tt] to prevent anyone's private variables overlapping with yours and still be able to access goApp.

So in essence: If you develop by best practices you only have local and maybe the one public global goApp variable many frameworks (codebook/mere mortals) use for a global application object. No private vars, no other public vars, because when you have goApp, all further things you want to be able to access anywhere can be made subobjects of goApp, goApp will be an object with many properties, methods, but also collections of further objects, thus this all is no limitation.

Further things having the nature of variables and having a very concrete scope are object properties. Don't use private variables for a scope between local and public, you have properties for the inbetween scope and it's much better suited for "variables" to live in the context of one form, one control or whatever object. You don't need anything else.

Bye, Olaf.
 
One more example on LIST MEMORY:
Code:
PUBLIC myvar1
LOCAL myvar2
PRIVATE myvar3
myvar4="private"
getscopes()
MODIFY file scopes1.txt nowait
MODIFY file scopes2.txt
FUNCTION getscopes()
   PRIVATE myvar3, myvar4
   LIST MEMORY LIKE myvar* TO scopes1.txt NOCONSOLE 
   myvar4 = "internal"
   LIST MEMORY LIKE myvar4 TO scopes2.txt NOCONSOLE

Notice a few things:
1. myvar3 is not listed, because PRIVATE myvar3 does not declare and create/initialise a variable.
2. Though LIST MEMORY is done within the getscopes function, the LOCAL myvar2 variable, which is not in scope of the getscopes function is listed. LIST MEMORY has access to the overall variable name table the Foxpro Runtime maintains, including access to local variables outside of their scope.
3. myvar4 is shown as (hid)den, this is the case, because the PRIVATE myvar3, myvar4 command reserves the name myvar4 for use within further code, the myvar4 coming from outside is still existing hidden and will be visible again, after code returns. It's value is unchanged.
4. myvar4 at one time exists 2 times, once hidden "private" and once current "internal". This way the private variables are even like local variables, same name is possible since the scopes are limited.

Bye, Olaf.
 
You were already be given some solid advice about variable scoping.

I would add that variable scope in VFP is private, by default, so if you use a variable before declaring it, VFP will set it as private. Beware that this occurs also when use functions that may create arrays.

For instance, in
Code:
LOCAL ARRAY Array_A[1]
LOCAL ARRAY Array_B[1]

DIMENSION Array_A[2]
DIMENSION Array_C[2]

ACOPY(Array_A, Array_D)
ACOPY(Array_D, Array_B)

arrays A & B are kept local, even when redimensioned, or copied from a private array; and, since they were not declared otherwise, arrays C & D are private.

Furthermore, don't forget that in VFP function parameters are also scoped. You can set parameters to be local either by using LPARAMETERS in their declaration, or by including the parameters list inside parenthesis, after the function declaration.

Finally, you may create a function to programmatically determine if a variable is local or not, but I think that its usefulness is somehow academic (made it for a fellow VFP programmer in another forum).
Code:
PRIVATE PrivateVariable
m.PrivateVariable = "x"

PUBLIC PublicVariable
m.PublicVariable = "y"

LOCAL LocalVariable
m.LocalVariable = "z"

CLEAR

? "m.PublicVariable =",VariableScope("m.PublicVariable", TYPE("m.PublicVariable"))
? "m.PrivateVariable =",VariableScope("m.PrivateVariable", TYPE("m.PrivateVariable"))
? "m.LocalVariable =",VariableScope("m.LocalVariable", TYPE("m.LocalVariable"))
? "m.UndefinedVariable =",VariableScope("m.UndefinedVariable", TYPE("m.UndefinedVariable"))

FUNCTION VariableScope (VariableName AS String, TypeAtCaller AS Character) AS String

	LOCAL MemoryNamespace AS String

	* make sure we're talking about memory variables
	IF UPPER(LEFT(CHRTRAN(m.VariableName," ",""),2)) != "M." AND UPPER(LEFT(CHRTRAN(m.VariableName," ",""),3)) != "M->"
		m.MemoryNamespace = "m."
	ELSE
		m.MemoryNamespace = ""
	ENDIF
	
	IF TYPE(m.MemoryNamespace + m.VariableName) != "U"
	* is visible at the callee, so it must Private or Public (no distinction can be made) 
		RETURN "P"
	ENDIF

	IF m.TypeAtCaller != "U"
	* is visible at the caller, then it is local
		RETURN "L"
	ENDIF

	* otherwise, it is undefined
	RETURN "U"

ENDFUNC

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top