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

what's the best practice to use and manage variables for big multi-user application 4

Status
Not open for further replies.

vj

Programmer
Nov 18, 2000
58
MU
hi everyone,

could anyone give me good ideas and thoughts on .. what is the best choice of variable types to be used (public,local or private) ,,, best practice on how to use and manage variables .... defining them for a big multi-user application !! ?? i however have always used public variables ... and never had any problems ... but i just wanted to get some ideas from the great minds here .

thankx alot
vijay
 
In the first place Variables are alsways a per User/Process thing, PUBLIC variables are not shared in multi user mode. Programming for shared Data Access has a good chapter in VFP.

The variable scoping is rather a topic for encapsulation of data and preventing side effects. It's best practive to always keep variables as small scoped as possible to prevent these side effects, and that's not only true for VFP, it goes in the same direction as encapsulation principles of OOP development. Like you have your few handles on a car to control speed and direction and have all the motor and electronic details "encapsulated" under the hood, you don't make all object properties public.

Besides that there is a bug about public variables, see
You better think about variable scopes in the future, even if you'd only do single user applications.

Bye, Olaf.
 
As Olaf says, multi-user has absolutely nothing to do with variable scope.

In general, a variable should be as narrowly scoped as possible. A function or method should be a wholly contained entity. Its variables should only exist within itself, therefore they should be local.

For variables used in several places across several functions and methods, they should be declared Private (the default) at a high enough level in the call stack so they don't accidentally go out of scope on you.

I am not an absolutist. Never say never. But never use public variables.

Having said that, I have used them. Usually when grappling with someone else's code where they didn't over-exhaust themselves in the design process. Any time you find yourself using the word PUBLIC in code, STOP! Think. Ask yourself (or ask here) "is there a better way?" There almost always is.
 
I completely agree with Dan and Olaf.

My own preferences are as follows:

1. Use Locals wherever possible.

2. If you really must share variables across functions, use Privates. But consider the alternative approach: passing the variable data as parameters (or returned values).

3. One place where Publics are useful is when passing variables to reports or menus. In particular, reports can only see the data in the current data environment and in whatever variables are in scope, and Locals cannot be in scope in a report.

4. Don't use Publics unless you have a good reason to. If you must use them, use them sparingly, and follow these rules: (i) Use a naming convention to make it obvious that they are Publics; and ii) Declare them all in on one place, preferably in a block of code near the start of your main program. What you should never do is declare Publics on the fly, in code buried deep in your application.

I hope this helps.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
>Locals cannot be in scope in a report
Untrue, I thought that for a long time, too, maybe it even changed with VFP9, but you can adress all variables in the scope of the code doing REPORT FORM for report control expressions etc.

Maybe your question background comes from SCATTER, which is the main thing crossing data and variables. You don't scatter to memvar, you either work on cursors or scatter name object, today. Also you use table/cursor/view buffering and set controlsources to table/cursor/view fields instead of variables, so you don't need to use variables in forms to display or edit data, you can bind the UI to the data more direct, even if you would like to have a buffer of changed you can either commit or revert, you don't need to use scatter/gather of variables for that.

Bye, Olaf.

 
Locals cannot be in scope in a report
Untrue, I thought that for a long time, too,

Looks like you're right, Olaf. I don't know why I always thought that. But never mind. It's a minor point, and doesn't change the main argument.

Mike


__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
>It's a minor point, and doesn't change the main argument.
That's true, it even allows you to narrow the scope of variables, even if you need to print them. So in that aspect it's a good thing.

Bye, Olaf.

 
I never declare PUBLIC variables. If I need a variable throughout an application, I declare it as PRIVATE at the very beginning of the application and prefix it with "g" (gWhatever) so that I know it is a public (global) variable.

In practice, I put the line "PRIVATE ALL LIKE g*" at the very beginning of the application so no matter what I don't have collisions elsewhere in the application.

FUNCTIONs and PROCEDUREs are always self-contained. Local variables are declared as "PRIVATE ALL LIKE <whatever>" at the beginning. External variables are always passed to and from them.

mmerlinn


Poor people do not hire employees. If you soak the rich, who are you going to work for?

"We've found by experience that people who are careless and sloppy writers are usually also careless and sloppy at thinking and coding. Answering questions for careless and sloppy thinkers is not rewarding." - Eric Raymond
 
I'll agree with the others. Don't use public variables. Like Dan, my code contains them only when I inherited the code.

Use local variables for everything unless you have a specific reason not to. In my code, pretty much the only two reasons I ever have for something other than local are:

1) I'm building a query to pass to a back-end server, and it needs parameters. Since I'll typically call a separate routine to do the actual SQLEXEC, the variables that contain the parameter values are declared private in the routine that sets the query, so the routine that runs SQLEXEC can see them.

2) One private variable called goApp in the main program of the application to hold the application object.

What no one else has discussed here (unless I missed it) is that one way you avoid public and private variables is by using properties. If you need to store something for the life of a form, add a custom property to the form and put it there.

You might find this article useful:

[URL unfurl="true"]http://www.tomorrowssolutionsllc.com/Articles/The%20Scope%20of%20Things.pdf[/url]

Tamar
 
For variable names, I use following prefix/convention

* For global variables : cx_ : see across the program
cx_Date = str(day(date())) + ' ' + upper(left(cmonth(date()),3))) + str(year(date()))

* For Local variables : t_ : Temporary variable used only in current method.
* For parameters : p_
* For return values : x_ : return from a function
* For index (loop) : ii, jj, kk, etc.
* For Field names : UPPER CASE
* For database and tables : lower case

It is a good idea to read convention from VFP help file regarding defining/declaring variable names.

nasib
 
mmerlin,

>I put the line "PRIVATE ALL LIKE g*" at the very beginning of the application so no matter what I don't have collisions elsewhere in the application
That alone won't make every g Variable private, meaning: Such a PRIVATE command is not defining all g variables private for the whole application scope.

PRIVATE is preventing private variables to "bleed into" your code, it hides variables which exist beforehand, it doesn't define variables. Since main is the start there are no previous variables, which could bleed in from outside, even not as command line parameters.

>Local variables are declared as "PRIVATE ALL LIKE <whatever>" at the beginning
That statement makes more sense, if you use "PRIVATE ALL LIKE <whatever>" at the beginning of every function, procedure, method, then all variables you create in your code, will be new variables and not change private variables coming from outside.

As you are such an old timer FoxPro developer I know you know better than how you explain it. If you "declare" local variable via PRIVATE ALL LIKE.., as you say, you never declare local variables, but only use private variables, as here:

Code:
test = "test"
? "before myfunc:"
List Memory like t*
myfunc()
? "after myfunc:"
List Memory like t*

Function myfunc
   Private test
   *Local test
   test="test2"
   ? "inside myfunc:"
   List Memory like t*

If you run this as is you see you have two variables test with scope "Priv"ate. The first one is associated with the whole prg, the second one with myfunc. And the first test variable is "(hid)"den. It unhides, after myfunc ends.

If you comment the Private line in myfunc and uncomment the Local line you'll see the local definition of the test variable also prevents usage of the private test variable, it also does not destroy the private variable, but it also doesn't hides it. Nebvertheless after the LOCAL declaration the name test refers to the local variable, not the private. If you uncomment both PRIVATE and LOCAL, you hide the private variable and introduce a local variable. Doesn't hurt.

If you never use LOCAL, you only declare private variables, if you always use PRIVATE in functions defining new private variables, you just end the private scope of variables already defined at that point and therefore your private variables become locally scoped, but LOCAL is there to create real local variables and private is there to introduce variables with a scope bound to the stack level. It's not scoped to a certain object or anything else, but only the call stack level.

The one advantage PRIVATE ALL LIKE l* additional to LOCAL declarations has, is that you could forget a LOCAL declaration and you still don't influence private variables.

I sometimes stated here or elsewhere, you could put PRIVATE ALL EXCEPT goApp at the begin of every function, procedure etc. That is even more radically refusing every variables bleeding in, except goApp, an application class instance to hold every globally needed data and functionality. But you have to understand every PRIVATE statement in code cares for all things in memory before that point in time and callstack, not afterwards. Beginning from then you can declare private variables with any name by just writing var=value somewhere and won't change such vars defined beforehand. the EXXCET clause can also be used to allow certain known and wanted private variables, eg in recursive functions. This can be overwhelming faster than passing variables by value.

So PRIVATE allows to define the namespace that you want to keep out and want to use to create new private variables starting their scope at the current stack level. But PRIVATE ALL EXCEPT goApp doesn't make every variable except goApp private. It just hides any private variable that may exist even accidentally and I can even forget to declare some variable LOCAL without the risc of overriding a private variable value. Nevertheless I use LOCAL all the time at the head of functions, procedures, and methods. Sometimes even with AS type, and often enough with comments to tell the meaning of the var. It's a good place for documentation and overview, instead of cluttering code with comments where variables are first set, for example.

Bye, Olaf.
 
hi everyone,

thankx for all the great inputs , so i understand ... the best thing is to avoid Public variables as much as possible .... i did find Tamar's article very informative and usefull. I really liked the idea of adding properties to the form and then placing values into them.
i'll seriously think on that rather than public,private or local variable types. and use public varibales only if they are required anywhere at anytime within the entire application.
right guys ,,, thankx for all the info ...

thankx alot
Vijay
 
Vijay - even if you use form properties, you'll still probably need local variables. But my experience is that I only ever need anything other than properties and local variables in the two cases I described earlier.

Tamar
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top