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!

Creating a function library 1

Status
Not open for further replies.

AndrewMozley

Programmer
Oct 15, 2005
621
GB
I would like to create one or more function libraries for use within a project. For example there would be a FormatDate() function, and many more project-specific functions.

I can create a .prg file with the functions defined and compile itinto a .fxp file. Am I then able to create a library file myfuncs.lib and put several .fxp files into it? If so, how do I do that please?

Then in my application I would like to be able to say

SET LIB TO MYFUNCS.LIB
and later on
cDisplay = FormatDate(DATE())
. . . that sort of thing.

(I am aware that I can create a define a class, create functions within that, then instantiate the class and call one of its functions.

oMyFuncs = CREATEOBJECT("MyFuncs")
cDisplay = oMyFuncs.FormatDate(DATE())

But I was rather hoping to call the function directly, if that is possible.)​
Thanks. Andrew
 
.LIB is not a Foxpro concept.

Put your PRG files into a project and create an EXE.

NOTE: since the invention of the project manager, FXP files are outdated. Even PROC files are relatively limited in utility. And we've had the project manager since dirt was new.

For maintenance purposes, it's generally easier to keep each proc in a separate file. However, the old way is still supported.
 
Andrew,

All you need to do is to put all your functions in a PRG file - one after the other. Then, at the start of your main program, execute this command:

Code:
SET PROCEDURE TO MyFunctionLibrary.PRG

where MyFunctionLibrary.PRG is the PRG in question. If the PRG file is not in the default directory or your search path, you will need to include the path with the filename.

And that's it. When you eventually build the executable, all the functions will be available, just like the built-in VFP function.

If you have more than one function library, execute the above command for each, but add the ADDITIVE keyword.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips, training, consultancy
 
As you can put many FUNCTIONs, PROCEDUREs and even DEFINE CLASSes into one PRG, it is already comparable to a library. SET PROCEDURE is the only thing you need, Mike has put that well. SET LIBRARY is for FLLs, see Foxtools.FLL as one sample delivered with foxpro. Read foxtools.chm in the Home() folder to read about what functions it offers. Most of them have meved into the main VFP runtime anyway, but REDUCE() and some other stuff.

If you would want to use that to create your own function, you would need to write these in C++ and compile a DLL project with specific extensions to an FLL. I'm sure that's not what you want or need.

Bye, Olaf.

 
Hello Dan

Thank you for the feedback. I certainly find the project manager useful, but was having difficulty in my project in calling functions which are defined in another .prg file in the project.

Thanks Mike.

That was the facility I needed and it works fine. Sorry for confusing the issue by talk of SET LIB – not sure where I got that from! As you mention I will include all the SET PROCEDURE calls in my initial program.

Andrew
 
You're welcome, Andew.

By the way, when I said "When you eventually build the executable, all the functions will be available", I didn't mean to imply that you are must build an executable. The functions will also be available if you just run in the development environment (you probably already realised that).

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips, training, consultancy
 
Add me to the "don't use procedure files" voices. They're a pain to deal with, and totally unnecessary.

Your problems finding PRGs is probably about pathing. At runtime, it's a non-issue; anything in the project is available. But when testing interactively, you need to use SET PATH to make sure that everything you reference is available. My practice is to create a PRG called SETPATH, which I store in a Utilities folder under the project root. Then, when I start working on a given project, the first two things I do in the Command window are:

CD <project root> -- which is usually in the MRU list
DO Utilities\SetPath

and then I'm set. If the main program changes the path (as they tend to), then I make sure that part of the shutdown/cleanup process is to reset the path, if I'm running interactively.

I'm sure most folks here have something similar, though there are many different ways to handle the design-time path.

Tamar
 
Tamar said:
Add me to the "don't use procedure files" voices. They're a pain to deal with, and totally unnecessary.

Really? That's interesting, Tamar. I've always used procedure files, and can't imagine how I'd manage without. I've never found them a pain.

So where do you put all your little generic utility routines that you want to carry around from project to project? I'm thinking of things like validating postal codes, or stripping blank lines from an address, or calculating the number of pixels in a text string?

I suppose you could put each routine in a separate file. Or perhaps create a "procedure object" (where each method is one of the routines). I've always found a procedure file to be the most convenient, but that's my personal taste.

The question of pathing is a separate issue. My approach is to place a SET PATH statement at the start of my main program:

SET PATH TO FORMS, REPORTS, CODE, CLASSES, GRAPHICS, MENUS, 3RDPARTH

The paths are relative to the project's root directory, which I switch to using your CD <MRU list> technique. I use the same sub-directory structure in each project, and only execute the above command when running in the development environment.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips, training, consultancy
 
Hello Tamar

At runtime, it's a non-issue; anything in the project is available

That is what I thought was the case, and what Dan also believes. However, I believe that it is not true : not all functions in the project are available. I have a program, MyFuncs in the project, and this contains two functions, Myfunc1() and Myfunc2().

This program is in my project. I then create a program, myprog.prg (also in my project) with this statement :

Myfunc1()

If I run myprog1, I get the error message : File ‘myfunc1.prg’ does not exist

But if I then alter myprog.prg, so that it says
Code:
SET PROCEDURE TO Myfuncs
Myfunc1()

. . . then the program works. It seems that in this case, the SET PROCEDURE command is required. It works fine.
 
Andrew, if you have multiple procedures in a single PRG, you have to SET PROCEDURE in order for code to find them. That's one of the reasons I don't like procedure files. If you put each procedure in a separate PRG named with the procedure name (so MyFunc1 goes in MyFunc1.PRG, and so forth), the Project Manager can handle finding everything.

MikeLewis, I never liked procedure files, even back when they were pretty much necessary. Once we got the Project Manager, I stopped using them and never looked back. All those utilities live in separate PRGs, unless there are related bits of code that also share common data, in which case, of course, I use a class.

As for pathing, I was specifically addressing the question of how to have your code work at design-time. I guess I should add that I'm in the "don't build until late in the game" camp. I test by running the main program from the Command window. Thus, making sure to SET PATH in the IDE is important. (I guess, if the Environment Manager had come along earlier, I might have settled on it as my standard way of handling this.)

Tamar
 
I agree on keeping individual procs in separate PRG files. As I tried to say earlier, there hasn't been any reason for SET PROC in many years.

The exception, of course, is third-party code products (using them or making them).
 
Tamar said:
I guess I should add that I'm in the "don't build until late in the game" camp.

Well I certainly agree with that. I'm surprised at the number of developers who do a complete build every time they run a test.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips, training, consultancy
 
I did a project hook, which puts all prg and vcx file names of the opening project into some meta data tables (paths and the file names seperated for SET PATH and SET PROCEDURE/SET CLASSLIB) and that could easily be extended to do automatic setup of the framework by doing those SET PATH, SET PROCEDURE/SET CLASSLIB additional to creating that meta data.

As of now I simply use that metadata to make the SET PROCEDURE/SET CLASSLIB in a loader.prg

The idea of such meta data is not my own, synching it with the project via a project hook is. I do SET PROCEDURE/SET CLASSLIB in both IDE and EXE startmode, I just skip SET PATH in EXE startmode, and that works fine.

I think it's very fine to have many functions and procedures, especially when they use each other, in one file, and use docuement view to get an overview of a prg. And the project manager gives an overwiev over the prg libs.

So Andrew, don't feel discouraged about putting many procedures and functions into one prg, there obviously are many "camps" as Tamar says. It's a matter of taste and whyt you can cope with best.

Bye, Olaf.
 
Mike said:
I'm surprised at the number of developers who do a complete build every time they run a test.

I've learned to do this nearly all the time. And even more, to copy the .exe into the proper (simulated) data directory, because doing so creates the exact environment you'll have when the customer is running it. No developer files in your development directory, but only the raw, naked environment the customer will see.

Subtle differences can crop in over time which take a few minutes here to find, a few minutes there to find, and over the long term it takes less time re-build and run from that data location than try to run from PRGs locally.

At least that's my experience. And in VFP, even building a 30MB .EXE takes only a few seconds.

Best regards,
Rick C. Hodgin
 
Well, what about debugging?

Even though you can DO your.exe to run in the IDE and be able to debug, you can't easily do component testing running the final EXE only from it's starting point. At least it always has escaped me how to do that easily. I know you can use NEWOBBJECT() specifying a class in an app or exe, I make extensive use of that, but that also put's it into the environment of the IDE and so why bother first compiling? It's a huge advantage to me to be able to always run within the IDE, that's part of rapid development. Let not doing a BUILD only save seconds, it does so multiple times each minute I test. Even if not setting "compile before saving" that's done on the fly anyway, when calling some proc/func or creating an object, so why waste that possibility?

Even though the debugger doesn't allow to change code while running (and will look forward to being enabled so in dotNET and perhaps VFrP), it's still very helpful for testing. Final usability and stability tests are done with the EXE, but during development I test from and in the IDE.

I've lowered the impact of the subtle differences (you may think of the same things I have in mind) to nil and there are very few usages of _vfp.startmode neccessary for that.
Also The framework I now use supports setting a mode from bare native VFP over setting classlibs, creating the goApp up to running the full app including the menu and login in the IDE and that works very nice.

Bye, Olaf.
 
Rick - I agree that it's important to test code in an environment like the one it'll run in. In fact, I've been known to do final testing in a virtual machine that doesn't have VFP installed at all.

But when I'm working on code, I want the code-test-debug cycle to be as fast as it can be. That's particularly important to me because I like to write a few lines of code, test that, then write the next few, and so on. (I can't always do things that way, of course.)

Whenever possible, I'll test what I'm working on right from the Command window without the overhead of running the application (even in the IDE) at all, until I think I have the whole thing working.

I think it was Whil Hentzen who said that you need to keep each step of the code-test-debug cycle shorter than the attention span of the programmer.

Tamar
 
Grateful for your contribution, Olaf; that gives me more confidence to develop a library of functions for re-use.

I recognise, however, that many VFP developers feel that it is better to keep functions in separate files to take advantage of the facility offered by the Project Manager.

Thanks to you all.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top