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!

Classes Procedure & Events

Status
Not open for further replies.

newtofoxpro

Programmer
Sep 16, 2007
301
IN
Possibility no no. I want to know best practices.

Small procedures which needed frequently in various places in the project, I kept in MainProc.prg & set proc to MainProc.prg in main prg.
PROCEDURE myDate
PARAMETERS InMyDate
RETURN DMY(InMyDate)
? MyDate(date())
Another way, define Main class & add these procedures and use them.
? Main.MyDate(date())

In case of MainProc.prg, I found that vfp search path is Main.prg,MainProc.prg,Current.prg,BacktoexecutionChain (Pls correct if wrong)

In case of Class, Class definition is in vfp's memory. Udf can execute faster. (Pls correct if wrong) But may be increase memory consumption.

Sorry, if already answered.
 
This is basically a question of trade-offs.

The question of search paths or memory consumption is not particularly relevant. Unless you've got a ginormous number of procedures, you won't see any significant difference in performance. But there are other factors to take into account.

Using a single PRG to hold the procedures (and referenced from SET PROCEDURE) has the advantage of keeping them all together in one place. On the other hand, if you make each procedure a separate file, it will be easier to use just the ones you want for a particular project, without the unused code being unnecessarily compiled and bound into the executable.

Another option is to create a class, and to make each of your procedures a method of the class. You might find that easier to manage. Again, it keeps everything together in one place, but it might mean unnecessary code being compiled.

I suggest you do what you feel most comfortable with. As I said earlier, it's not going to have a big impact on performance in most cases.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
I agree with Mike.

I tend towards individual PRG files, one per proc, just so I only drag in the ones I'm using and because I think it's easier to find stuff. But there's a valid argument to be made for grouping your procs by function (i.e. all date functions, all string functions, etc.) into classes dedicated to those activities.

One word about class design though: using a single class for all procs would break most of the rules of OO design. It would result in one class that doesn't do any one thing particularly well but does little bits and pieces of a lot of things. A class from which you beget an object should in general represent a real thing in the real world. That's the ivory tower theory, anyway.

In the real world, implementation details can muddle how the ivory tower theories get implemented. In the end, it's a packaging issue. Do it the way you feel most comfortable. One of VFP's strengths is that there are always at least three ways to do any one thing, and a case can usually be made for either of them in specific circumstances.
 
There's another problem with using a class instance vs procedures (doesn't matter if multiple prg/frx files or a single):

A class instance always is created in the current datasession (despite it's a session class creating a new session or a form/formset with a private session of course). The side effect of that is often underestimated: If you have a function working on an alias given by a parameter, you may not find that alias when executing a class method, a procedure always executes in the current datasession.

Even if you're an OO purist, you would not do everything just in class instances. VFP lacks some of the advantages of .NET, eg static classes or extension methods. If you're familar with this you could compensate not having simple proceddures and functions with these concepts in .NET, but on the other side then will need to think about thread safety and other things you won't need to think about in VFP.

Anyway, you can still create a class instnace for general purpose functions, as long as it doesn't adress any workareas. That would be a limitation you could live with, if you would implement all data related functionalities in classes, which are instanciated in the right context, eg the right datasession, anyway. But it's hard to remember there is such a limitation and the pitfall of a class instance bound to a session can't be circumvented. You can switch sessions of a class by adding a SetDatasession method.

But would you do this:
Code:
goGeneralFunctions.SetDatasession(SET("DATASESSION"))
goGeneralFunctions.GetReccount("somealias")
instead of this:
Code:
GetReccount("somealias")

Aside of there being a function RECCOUNT("somealias"), it's just a simple example and the real case might be a more complex function.

There is another reason to use functions and procedures even in a mostly OOP designed application. The native language itself has many functions and commands and so its design is already in that direction of imperative code rather than behavioural or declarative programming. Other than C++ or C# it has a huge set of native commands instead of just a small set and a bulk load of framework assemblies no single developer ever will have an overview of. If you don't like the mainly imperative concept of VFP you should really put it away, you'll get lost in writing a new language, if you eg create a string class implementing an OOP style of the VFP family of string functions. This'll end up being perhaps more elegant and modern, but also less performant and with your latest questions you seem to aim for performance.

Not, that a single goGeneralFunctions = CREATEOBJKECT("generalfunctions") is a performance hit, but if you adapt the VFP language to todays conception of "everything is an object", you'd a) not stay with a single class and b) burden it with mere perfectionism instead of pragmatism and only really start developing after having invented VFP.NET.

Of course there also is a downside of implementing mere functions. One thing not to do is ending up redefining the language by putting every often used three-liner into a user defined function, only to find out later more experienced, VFP already can do that in a one-liner - as a side note: Take a look at what you can do with intellisense and macro definitions. Another thing is, code calling user defined functions also is less good documenting where to find the implementation in comparison to calling the method of an object named like the class it came from. But when using user defined functions coverage profiling and debugging will point you to where the call goes and as you don't have multithreading (at least not native) debugging is less complex and easier to follow, so that again speaks for functions.

There are good reasons for classes, when it really comes to the core design of an application, of course, when you really need OOP principles like inheritance and separation of concerns, etc.

Bye, Olaf.
 
I'm firmly opposed to procedure files and much prefer stand-alone PRGs. This was strengthened in the last couple of weeks as I started working on a project that arrived with several procedure files, one of them over 100,000 lines of code, containing over 1,000 routines. I've just contributed to the Thor Repository a tool that takes a procedure file and breaks it up into its constituent routines.

Tamar
 
You know, Tamar, I generally agree with you but I'm also in the "never say never" camp. I've seen perfectly sane applications that used stand alone prgs for special-use procs, but app-wide procs were in a proc file. (Or course that breaks down completely when you have more than one app or more than one proc file.)

I'd actually settle for a proc file in the mess I inherited. It's more than a dozen applications and not a function anywhere in the lot. Not. One. Nary an error handler in the lot either. (Well, there are both *now*! <g>)

 
Tamar,

I'm with dan here, but at the same time like your idea of automatically splitting up single proc files. Without looking at the newest Thor version, I assume your tool takes a prg file as parameter and doesn't iterate all prg files of a prg file automatically. The latter would be an idea and a goof compromise would be to list prg files of a project and let the developer pick the ones to split up.

Bye, Olaf.
 
PROCEDURE _mySql(inString,inAlias,inOrder)
CREATE CURSOR mQuery (Fld1 c(80), ......)
SELECT &inAlias
SET ORDER TO (inOrder)
SET KEY TO inString
SCAN
SCATTER TO mVariable
INSERT INTO mQuery FROM ARRAY mVariable
ENDSCAN
SET KEY TO
SELECT mQuery

Test A : I kept this proc in Class and run for 100 times
Test B : I kept this proc in Proc.prg and run for 100 times

if I did not find good difference.
 
I did not find good difference.

Not surprising. Your SCAN and INSERTs would take considerably longer than finding and compiling a procedure or an object's method code. As we've been telling you, performance is not a significant factor in this decision.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
You quoted yourself here:

newtofoxpro said:
In case of Class, Class definition is in vfp's memory. Udf can execute faster. (Pls correct if wrong) But may be increase memory consumption.

Actually anything that already is in memory should go faster.

The main thing about the VFP language to know is, it compiles into opcodes, similar to .NET MSIL or java bytecode, it's just the final code. PRGs compile into FXP files and code in VCX or SCX in the same way from the Methods memo into the Objcode memo. This opcode is executed by the VFP runtime DLL, so in general this could be considered as Interpreter instead of compiler. VFP also has no linker and doesn't allow early binding of DLLs or LIBs, therefore. It's written in C++ but it isn't C++

If you start a PRG for the first time the FXP will be generated, also if the PRG file is newer than the FXP, VFP keeps things in memoy/cache, not only classes. But indeed if you instanciate a class it will be in memory in a more direct way than an FXP, not just cached. You can CLEAR CLASS, but only once there is no instance of a class in use, which also indicates there is a special memory for classes.

Anyway, once code is loaded it's loaded. You won't see much differences in calling a method instead of doing a prg or calling a function.

If you're really interested about VFP internals as a new foxpro user, I could point you to articles and white papers, but you should perhaps first stay with the core language instead of diving so deep into details. I know this is a decision you later can't easily do another way, but you will be able to do things as Tamar just mentioned, writing code that modifies code. So you could also change a class to separate prgs later or vice versa, it's not that advanced, you merely use a few string functions, and put files together in strings you then store via STRTOFILE(). So it's not a decision you later will regret and have a hard time to change. Only once you begin using properties of classes you won't have an equivalent in PRG functions, functions don't offer inheritance and statefulness, but that should be obvious.

Bye, Olaf.
 
Olaf said:
If you start a PRG for the first time the FXP will be generated, also if the PRG file is newer than the FXP, VFP keeps things in memoy/cache

That reminds me of another factor to take into account. If you have a huge procedure file with many thousands of procedures and perhaps tens of thousands of lines of code, and if you are working in the development environment, you will notice a delay when you execute SET PROCEDURE the first time after you have edited the file. This is because VFP is compiling the entire file at that point. This is in contrast to the situation with separate PRGs, where each file is compiled on the fly the first time it is used (after an edit).

So, if the single file contains many procedures that you never actually use, that will be wasted time. In practice, it's probably not enough to worry about. And, importantly, it doesn't happen when running from an EXE (because the compilation will have been done at build time). Still, it's something to keep in mind.

Mike


__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
> it doesn't happen when running from an EXE

Very true, you don't have compilation in an EXE, as it is composed of compiled code. I'm not sure an EXE even only contains the frx files if you uncheck "Debug info" in project informarion before building an EXE.

But it also reminds me of the important fact an EXE also just contains the compiled opcode, it merely is an APP with a little bootstrapper Windows can start. This boostrapper merely launches the VFP runtime and let it start executing the main file of the former project. So an EXE is not compiled into ASM or C++ and there is no JIT compiler compiling VFP opcodes to assembler for the present CPU, nothing like that is done.

Bye, Olaf.

 
Dan, for sure, a procedure file is better than no procs/funcs at all. But I've seen too many applications that grow these enormous procedure files and never prune them. I also had one application where testing changes in the procedure file required deleting or renaming the most recent EXE.

This latest example with over 100K lines was just absurd. And it broke GoFish. (In retrospect, that might be the Chr(0) I found in the file, that also broke other tools.)

I don't always break up proc files when I encounter them, but I'm doing it more and more.

Tamar
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top