James,
yes, that's exactly what you get using /a.
EMG
James,
yes, that's exactly what you get using /a.
EMG
James,
The problem with legacy code is there is often so much to clean up ! I took a program that evolved from its DOS origins 32 years ago, moved it to windows, and kept adding on "functions". It worked, but I never gave much time to optimizing, or cleaning up variables ... just trapped problems and fixed it.
When I started my "optimization project" 10 months ago, and started developing classes, it certainly cleaned up a lot of the code. However it's hard to maintain 100% concentration on such a massive project.
Ultimately I'll be able to eliminate 100% of any automatic declarations, and have everything super fine tuned ... but it is a massive project. It's one thing to convert the shell of a program, but yet another to maintain / convert all of the supportive business logic !
Until then, I'll just accept the auto declarations ... and be happy when I actually have a .prg compile without any !
Tim
Friends,
perhaps you misunderstood the purpose of /a. It just avoids the need of using MEMVAR, that's all. So you still have to declare private and public variables using PRIVATE and PUBLIC keywords and still have to access them using M -> prefix. So using /a you don't lost any of the benefits of variable declaration.
EMG
So using /a you don't lost any of the benefits of variable declaration.
James Bott wrote:There is a warning generated for cDate in the DoSomething() function.
Function Main() #include "fivewin.ch" public cDate memvar cDate cDate:= dtoc(date()) doSomething() Return nil Function doSomething() msgInfo( cDate ) // warning generated here return nil
Function Main()
memvar cDate
#include "fivewin.ch"
public cDate
cDate:= dtoc(date())
doSomething()
Return nil
Function doSomething()
msgInfo( cDate ) // warning generated here
return nil#include "fivewin.ch"
memvar cDate
Function Main()
public cDate
cDate:= dtoc(date())
doSomething()
Return nil
Function doSomething()
msgInfo( cDate ) // warning generated here
return nilThanks Biel! I thought it that way ("... Declaring MEMVAR inside a function gives function scope to the var's declaration, so it should be moved in front of both functions.") but then I didn't put it in the code.
Its a good think to have someone paying attention.
Thanks again.
PD: We should organize another meeting like the one in Barcelona, what do you think?
Carlos,
Thanks for your input. I haven't tried your code yet, but it appears that it won't solve the issue I am trying to solve. Moving the MEMVAR to the top of everything will prevent warnings for undeclared PUBLICs, but that is not what I need.
I am trying to get warnings for every undeclared variable used in every function. This forces me to declare all of them at the top of the function. Note that many of the functions in this app are hundreds or even thousands of lines long. So I need to document all the vars to help me understand the function and hopefully make them more bomb proof. The code is also complicated since many, if not most, of the variable names are seemingly randomly generated strings of letters with no meaning. I presume this was done since when I first worked with this code many years ago, there were no variable declarations, so everything was private. Thus every variable name had to be unique across the entire program.
Maybe I actually could do both. First your way, declaring all the publics at the top of the file, then I would only get warnings for undeclared locals. Once I got all those declared, then I could remove the MEMVAR declarations and get warnings for all the publics. I will write some test code to try this out. Hmm, I haven't even thought about privates yet.
Your thoughts?
James
James Bott wrote:I am trying to get warnings for every undeclared variable used in every function.
FUNCTION MAIN()
PUBLIC cVar := "This is a test"
RETURN NIL
FUNCTION TEST()
? cVar // warning here
? M -> cVar
RETURN NILEnrico,
Well, I see your point and in the long run perhaps it would a better idea, but prefixing every public var use is going require probably tens of thousands of prefixes. And I won't be able to tell if a function is using publics just from looking at the top of the function. Using the MEMVAR statement would only require one change per function and I get the documentation. There are 980 functions in this program so you see the magnitude of this issue.
OK, I could put a comment at the top of each function listing the publics being used (that just came to me).
Will try both methods on some of the code to give them each an evaluation.
Thanks for the input.
James
James Bott wrote:
I am trying to get warnings for every undeclared variable used in every function. This forces me to declare all of them at the top of the function.
James Bott wrote:
Maybe I actually could do both. First your way, declaring all the publics at the top of the file, then I would only get warnings for undeclared locals. Once I got all those declared, then I could remove the MEMVAR declarations and get warnings for all the publics.
May be it's not so easy. It depends on how vars are being used: a LOCAL can't replace a PRIVATE, because the scope of PRIVATEs go beyond the current function to the called ones. Fortunatelly in your case every var has it's own (weird) name, so it will be easy to find the usage of vars outside the funtion it's been declared and add it to the function parameters.
What's your plan? PUBLIC => STATIC and PRIVATE => LOCAL?
SublimeText and xEdit has wonderfull features to refactorize your code, replacing strings in all files simultaneously.Yes, my editor will do that.
Anyway, it seems to be a significant task. May be a code analyzer can help. There were several for Clipper, although I've never used them.