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!

Private Variables not restoring to their original values

Status
Not open for further replies.

KALP1

Programmer
Aug 26, 2016
102
IN
I have 1 procedure say Abc() in which 1 private variable 'Pety' is defined to be true. In that form 1 have 1 command button which shows a summary report.On entering on any record of that summary report,proc. abc() is called again with pety = .F. . Now when I esc from abc() procedure(proc. which was run second time),summary report is displayed. When I press esc from this report and suspend prog. I find Pety's value = .F. although It should be .T. as it was declared as private in 1st abc() procedure
 
Hi

This is a scope issue, if your function has a variable that is private, and that variable has it's value changed within the function that change will only be visible within that call to that function.

You need a variable with scope 'above' the function - either a public variable (generally disliked these days) or a field or property on your form, personally, I would put a checkbox on the form that is not normally visible to my users - but which I could see for debugging - so I could 'watch' the value change



Regards

Griff
Keep [Smile]ing

There are 10 kinds of people in the world, those who understand binary and those who don't.

I'm trying to cut down on the use of shrieks (exclamation marks), I'm told they are !good for you.
 
As Griffs explanation should indicate: You misunderstand private variable scope.

A short explanation of the behavior is:
1. The scope of a private variable is beginning on the call stack level it is generated on and continues throughout all called routines from that level onwards.
2. Running a form is not comparing to calling a function, only the forms load and init will have a private variable in scope, if you DO FORM from the code generating the private variable. Any further event or method running inside the form has no knowledge of the private variable anymore.

Even shorter: Call stack level isn't similar to object parent/child hierarchy, or also: You don't call "the form", the form is not a single method, it's an object of which you initially only call Load/Init, the rest then happens, but since you already returned to ABC() that call stack already was emptied again.

You might have a difference when making the form modal, but I would recommend the same thing Griff does: Receive the variable value in the form Init and store it in a form property "Pety", then let your code use THISFORM.Pety. For a report to see this value, copy it into a private variable again before REPORT FORM, ie just put Pety = THISFORM.Pety before the report command.

Bye, Olaf.
 
Oh... I got problem after debugging code for 1 day. It was typo problem.
I had written
private a1,a2,a3;
a4,a5.....pety

store .f. to pety

After a3 -> comma was missing which was root cause of problem. Strange program compiled without giving any error.
Sorry for taking your time olaf and Griff.

As I was not getting cause of problem, I had already done as olaf suggested to make pety as form's property Thisform.pety


 
What VFP version are you using, VFP6, right? I had such errors in code, which only showed up after upgrading to VFP7 later. Yes, this is a bug maybe never even mentioned in any bugfix list of MS.

Anyway, PRIVATE is not a command to declare private variables. By all means better stay away from private variables wherever you can, especially if you use PRIVATE and thereby hiide the current/previous state.
Using PRIVATE myvar as start of a recursive function for example is identical to LOCAL myvar, as the myvar variable is stopped from being accessed and modified with that. PRIVATE rather declares which variables should not be influenced when they already exist, you hide them and end their scope and allow these names to be reissued for new private variables. Such use is quite useless and means you rather want the variables to have LOCAL scope.

Bye, Olaf.
 
Olaf, I am using VFP 9. I had just explained my problem in simple words. I have a program with 5000 lines with many procedures which use Pety variable. Depending on .t. or .f. Cursors are updated in corresponding columns . Now when this program is again called for Pety = .f.,I get its value in all sub procedures, so I thought it to make private. Any way making Thisform.Pety also worked.
Correct me if I am wrong.

 
Strange program compiled without giving any error.

Well the semi-colon will of course act as a line continuation marker. So your declaration is identical to

[tt]PRIVATE a1, a2, a3 a4, a5.....pety[/tt]

Note the space between a3 and a4. You would think that would be illegal, but the fact is that you can put all kinds of stuff in a PRIVATE declaration without getting an error. For example:

[tt]PRIVATE a1, a2, a3 ##+$%^... a4, a5[/tt]

This does not produce an error (unlike the equivalent in LOCAL, which would produce a syntax error). I think the reason is to do with the fact PRIVATE doesn't actually do anything - it is more like an instruction to the compiler - whereas LOCAL actually creates variables, so it takes some action at run time.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
>"Correct me if I'm wrong"
Well, you don't at all respond to my call to action to avoid private variables, unless I take "5000 lines" as "impossible to change in that regard".
I maintain much larger code bases (10fold as many lines easily) and you can manage to incorporate better coding styles.

You might look into other discussions about PRIVATE scoping:
thread184-1706496
thread184-1674124

Bye, Olaf.
 
Mike,

another reason to avoid PRIVATE unless you know better, if you ask me. Actually my VFP6 vs later compiler experience was from LOCAL, not PRIVATE.

Bye, Olaf.
 
Ok Olaf , I will avoid using private variables. Making them as form's property is much better options I suppose. Is that right method to manage code or something else.
 
Yes, the rule of thumb is - keep the scope of anything as small local as you can do.
Something the form should know somewhere in a form method later than Init should be made a form property.
If a chain of code (functions,methods, whatever) works on a value, pass it on as parameter and when needing feedback/modification pass it on by reference.

PRIVATE variables in VFP have a very unique way of scoping I don't know of any other programming language, which is no big plus. It's not a concept that is unique in the sense of uniquely brilliant, but rather a uniquely quirky way of defining a less public variable. Private scoping as said is making a variable visible not only to a certain object but any code being called. So if a private variable is defined before calling a modal form the variable stays in scope, alive. That in itself is quite harmless, a form can then make use of it, but when the form calls a PRG, that also has that private variable in scope and it may influence the variable way or be influenced by it, maybe because it also uses that same name but for another meaning of it. You code loses its coherence, its encapsulation this way.

Private variables are a feature of VFP, which may have been of good use at some stage of the language, but has become obsolete and outdated by modern ways of coding, eg the scoping of variables and properties OOP offers. Private there rather means an opposite thing, only locally visible, only usable in the class itself and child classes, not accessible from outside.

Bye, Olaf.
 
Hearty thanks Olaf for sharing valuable info., as till now I used to prefer using private variables in a chain of code.
Good Stuff for Programmers to remember.
 
Well, just to state the obvious: If think of a chain of code as always working on the same object, it may be worth to put all tht code into a class, which by definition can have its own state in the form of properties. If I talk of a form calling a PRG it shouldn't be a PRG very spoecific to that form, rather a very generally reusable functionality, for example asking for the permission of a user for a certain object Such things can also be put into a global object, but it shouldn't become a class doing everything you use from more than one place, it should be really something of very global interest. Sometimes it might also end up in some base form class every other form inherits.

Thinking about what code needs access to which data is a starting point thinking about class design, thinking of a bubble with few interfaces needing to go in and out, self contained and yet only specialised on a very concrete and overseeable topic.

Bye, Olaf.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top