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

PUBLIC, PRIVATE & LOCAL

Status
Not open for further replies.

IRABYY

Programmer
Apr 18, 2002
221
US
I am starting this thread by suggestion from Mike Lewis.

My statement:

PRIVATE mem. vars. belong to a class definition. For everything else there are LOCAl and PUBLIC mem. vars. And the less PUBLIC mem. vars. - the better.

Consequently, implicit memory variable's declaration - which makes it PRIVATE - in procedural modules has to be avoided. (This includes implementation of SCATTER MEMVAR command in procedure and/or function as well.)

Everybody is welcome to join the discussion.


Regards,

Ilya
 
frikfrak2
So if I have:

xx="JCAT"

what type of variable is this?


ChrisRChamberlain (Programmer)

PRIVATE, by virtue of the fact that you did not declare it to be LOCAL or PUBLIC.

I should also add that it's called implicit memory variable declaration.


Regards,

Ilya
 
Actually the variable xx MAY not be private, there is scope to consider - if the variable is initialised with a value outside of a function or procedure (i.e. in the top level of code for an application) then it's scope will make it PUBLIC to all intents and purposes by default.



Regards

Griff
Keep [Smile]ing
 
GriffMG (Programmer):
if the variable is initialised with a value outside of a function or procedure (i.e. in the top level of code for an application) then it's scope will make it PUBLIC to all intents and purposes by default.

True. But then I would rather explicitly declare it as such, i.e.

PUBLIC gcMyMemVar

That's my personal preference: all memory variables should be declared - with the scope defining command - explicitly.



Regards,

Ilya
 
That's very true, but FrikFrak2 hadn't declared his variable explicitly in his question...

Personally I tend to declare 'top level' variables as PUBLIC along with a comment to indicate what they are for (originally!) and use PRIVATE variables in functions and procedures as much as possible - I don't often use the LOCAL definition, which is just laziness on my part.

Sometimes, I break my larger functions down into smaller segments and it's easier to use the variables which are still 'in scope' from the parent functions rather than passing them as parameters - [red]shoot me! I know it's bad practice, but so are multiple exits from a function and changing a variables type - and most people seem to do those![/red]



Regards

Griff
Keep [Smile]ing
 
OK

So if I have XX="" at the very begining of my program then somewhere in the code I have XX="JCAT". It's a PUBLIC variable automatically? Yes?
 
Hi FrikFrak2

Yes, to all intents and purposes, the XX would be public - technically it wouldn't, but it would be in scope for all procedures and functions so unless it was overidden by a later declaration it can be considered public.

Do you want to e-mail me the code with the leak?


Regards

Griff
Keep [Smile]ing
 
This program is always a good one to demonstrate
the concept of private variables and the possible need for declaring them.

Run it just as it is and then remove the PRIVATE declaration from the procedure called changex.

It demonstrates the danger that is lurking when you do
not declare variables.

You can also replace each of the declarations with the LOCAL or PUBLIC options and observe the results.


PRIVATE x

x = 5

DO changex

? x
RETURN

PROCEDURE changex
PRIVATE x
x = 2
RETURN


Don
dond@csrinc.com

 
FrikFrak2

My address is Martin.Griffin@Finedata.com

Regards

Griff
Keep [Smile]ing
 
Don,

in your example, i would have thought hte outpupt to be x=2 but to my surprise x=5...


WHY?

If in your proc. you say x=2 then then last value to x is 2 ergo =2... No? Well, foxpro says no, x=5... HA!..go figure.... why?
 
GriffMG (Programmer):
and use PRIVATE variables in functions and procedures as much as possible - I don't often use the LOCAL definition, which is just laziness on my part.

Sometimes, I break my larger functions down into smaller segments and it's easier to use the variables which are still 'in scope' from the parent functions rather than passing them as parameters.

Consider the following
Code:
PROCEDURE One

lnMax = ADIR(laFiles, ADDBS(lcPath) + "*.*", "D")
FOR I = 1 TO lnMax
   IF ATC("D", laFiles[I, 5]) > 0 && Subdir.
      DO Two WITH ADDBS(lcPath) + ADDBS(laFiles[I, 1])
   ENDIF
NEXT I

RETURN
ENDPROC

&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

PROCEDURE Two
PARAMETER tcSubDir
lnMax = ADIR(laFiles, tcSubDir + "*.*", "D")
FOR I = 1 TO lnMax
   IF ATC("D", laFiles[I, 5]) > 0 && Subdir.
      DO Two WITH ADDBS(lcPath) + ADDBS(laFiles[I, 1])
   ELSE
      && Some code
   ENDIF
NEXT I

RETURN
ENDPROC

I do not have to elaborate, do I?

And even if you declare I and laFiles[] as PRIVATE in One, unless you re-declare them as PRIVATE or LOCAL in Two, you are in for big trouble. Don't you agree?

(This was what happened with my coworker some while ago with similar design. He's spent days trying to figure out what's wrong, why his I counter value changes all of a sudden, and VFP's giving him "Subscript is outside defined range" error message.)

Considering that, I'd rather be safe than sorry - [wink] - and declare all my mem. vars. explicitly and never PRIVATE. If I need to modify a mem.var. - I'd declare it LOCAL and pass by value to a function (where, BTW, parameters are also made local). And then:
Code:
lMemVar = MyFunct(lMemVar)


Regards,

Ilya
 
I take your point Ilya, but I automatically declare all parameters as private - it's force of habbit like the select, skip and enddo that I put together whenever I write a do while...

That said, once in a blue moon I do forget to privatise the odd counter - like lnMax or I! but that's life!

Martin

Regards

Griff
Keep [Smile]ing
 
my value xx is not a counter. it's just a variable for which the the value gets changed. :)
 
To FrikFrak3 ...

It is unfortunate that you find the result of my little example so "amazing". That means your understanding of these concepts is flawed. I would try to explain these concepts but have found that it is not easy to do so without rambling on to the point of additional confusement.

I would suggest you try creating some little test programs like the one I gave you to help you develop a strong understanding of this. Without that I am afraid you are going to struggle with "weird results" that are almost impossible to figure out.



Don
dond@csrinc.com

 
frikfrak2 (MIS):
my value xx is not a counter. it's just a variable for which the the value gets changed. :)

I know, it was just a demonstration of the danger of using private mem.vars. in procedural (PRG) module.
That's why my first suggestion to you was to declare it as LOCAL and see where you get a "Data type mismatch" or "Illegal redefinition" error message. FYI, all mem.vars. in FP are of type U[ndefined] and carry .F., untile you initialize them. Once initialized, they become of data type of the value they've been first initialized with, i.e.

LOCAL lcMemVar && Undefined, it's value is .F., though char type suggested by the second prefix.
...
lcMemVar = "QWERTY" && Becomes of character type.

And if later

lcMemVar = 1

"Data type mismatch" error message springs up.

HTH.


Regards,

Ilya
 
Hi,

OK, in retrospect, should i say XX="" at the begnnfin of my program?

then when I get down to assign a value to xx I woouold say xx="blahblah" and it would be good? right?

all I have to do is add

XX=""
at the begging of my code or should I put

LOCAL xx
xx=""

Which is the best way?
 
Ilya,

I know you started this thread in response to some remarks in FrikFrak's thread. You've had some good replies, but let me just address the point you originally made.

You said: PRIVATE mem. vars. belong to a class definition. For everything else there are LOCAl and PUBLIC mem. vars. And the less PUBLIC mem. vars. - the better.

I said that I thought there was sometimes a case for using privates and even publics.

You sometimes have to use privates when you are calling some processing code from a method, where that code cannot accept parameters. A couple of examples: calling a menu from a method; and printing a report from a method. If the menu or report needs to reference a variable which is held in the method, that variable has to be private (or public).

As for publics, I agree that it is best to use these as little as possible, but again there are cases where they are useful. For example, in one of my applications, I constantly need to know the current user's permission level. By holding this in a public variable, I can save having to constanly pass it around as a parameter or the overhead of reading it from a file.

Of course, I agree that locals are the preferred choice. I'm just talking here about exceptional cases.

Mike


Mike Lewis
Edinburgh, Scotland
 
Instead of using a variable, why not create an object in your root program, then add properties to it when/as needed, and refer to them as MyObject.Variable1, etc.? The object would remain until released or the program ends.

Harry
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top