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!

Save Functions

Status
Not open for further replies.

alisaif

ISP
Apr 6, 2013
418
AE
Hi

Where is the best place to keep all the functions routine in system like below:

Code:
? IpInternet()

FUNCTION IpInternet()
  LOCAL My AS My
  My = NEWOBJECT("My","My.vcx")
  ERASE "IP.txt"
  IF 0 = My.Computer.Network.DownloadFile("[URL unfurl="true"]http://www.whatismyip.org",[/URL] "IP.txt")
    RETURN FILETOSTR("IP.txt")
  ELSE
    RETURN ""
  ENDIF
ENDPROC

If I want to avail this routine on a form what I have understood is I will call IpInternet() from a command button and keep (FUNCTION IpInternet() in a prg. Isn't it? Or I have to dedicate a prg to store all these functions routine.

Please guide..

Thanks

Saif
 
Saif,

Opinions differ on this point.

First, can we assume that this is a generic function that you want to call from many places in your application (and maybe from other applications)?

If so, then my own preferred approach would be to put it in a procedure file. This is an ordinary PRG that contains all your generic functions and procedures. At the start of your program, use SET PROCEDURE to open it, then call the functions from anywhere you like. I like this approach because it keeps all these routines together, and you always know where to find them.

However, many programmers prefer to keep each routine in a separate PRG file. This helps make them self-contained, and it's also more efficient, because only the functions you actually call will get bound into your EXE.

A third option is to define a class that contains all the generic routines - with each routine being a method of the class. Instantiate the class as a global object at the start of the app. Then call the the appropriate method as needed.

Finally, if the function in question is specific to a form (in other words, you will never call it from anywhere else), then make it a method of that form.

As I said, everyone has their own preference in this matter, so do whichever method you feel most comfortable with.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Hello Saif,

in your specific case I'd rather want this as an application class property, which might initially get the ip address via the class init or via a propert< access method just doing this unless the ip property is not yet a valid IP, because the IP doesn't change often.

More general speaking, the approach to have a function per prg was recently also promoted by Tamar Granor, here or over at MSDN forums. Instead of lcip = IpInternet() you'd then call DO IpInternet.prg TO lcip and besides the advantage Mike already mentioned, you can also extend that to usage in a seperate EXE or APP, via the call syntax DO IpInternet IN some.EXE/someAPP TO variable. That is not possible with a procedure (DEFINE PROCEDURE) inside a PRG inside an APP or EXE.

That said I rather make use of this seperation of common code used by several applications as APPs with classes instanciated via NewObject(), which allows a paramterisation to instanciate a certain class of a certain vcx embedded in a certain APP or EXE. And for that matter I group classes inside VCXes, I don't go with the single class per vcx or single procedure per PRG.

In creating, maintaining and developing libraries, the advantage of several procedures and functions within the same PRG is the editing of a family of such generic functions with the same topic, eg math functions, date functions etc., the same goes for a vcx with several classes and I prefer the grouping by topics or application domains. So I keep the list of prgs low.

You can always argue, that the seperation into single class vcxes and single procedure PRGs is enabling the atomic composition of things. But the project manager also gets bloated with names, I rather seperate the different inheritance levels with seperate prefixes so the more specific classes I develop from framework base classes and use in an application, which are typically at the end of the inheritance chain, sort to the top and the framework stuff I also share with other projects is listed towards the bottom, then I can still have the best overview over the classes, by expanding the library nodes to see the single class names within the poroject manager classes tab.

Bye, Olaf.

 
Always think, "Separation of concerns". It isn't the job of a form to download a file from the Internet. You have a few options. One is to just keep it in a separate prg and call it. Another is to have a class library of internet functions. BTW, the function name IPInternet does not describe what the function does. I always try to name methods and functions in a way that you know from the name it's functionality. Using a VerbNoun construct so, something like DownloadIPFile is good. Even better is to make this a generic function. Take the URL and the filename as parameters. In that case, name the function DownloadFile.

Craig Berntson
MCSD, Visual C# MVP,
 
>what I have understood is I will call IpInternet() from a command button and keep (FUNCTION IpInternet() in a prg. Isn't it?
To add an answer to that in short: Yes.

Craig has put me into the perspective of the answer you might rather expect, than a general discussion about project composition and general modularisation.

Any FUNCTION is something, you can only define in a PRG file, similar to PROCEDURE. You also need SET PROCEDURE TO that.prg to make that function name available whereever you want to use it (and SET PROCEDURE is for PRG files with both FUNCTIONS and PROCEDURE or mere PRGs being a function or procedure by itself, eg starting with a parameter statement themself)

Craig correctly already wwarend about adding this to the form, because to retrieve the internet IP is not the job of a form. But you could also do that, just not as a function. To extend a form with further code you would use the "New Method" menu item of the Form menu and after having defined the method name then can add code to that method, like you can add code to the Click event of a button or any other form or control method or event. It's about the same way you extend visual classes.

This way the function body could also be part of the form, but it would only be good practice to add a form method, if the code you put inside the method is acting on the form itself or it's controls, generic code rather belongs into seperate PRG files or classes.

Fiunally I come back to my idea of adding this to an application class. In many VFP application frameworks your main.prg starts an application class as object in a variable "goApp" and the internet ip address could be one property of that object, eg goApp.internetIP. That would also be a viable way to add this to your application, because I assume you can use the ip address in many places of your application, not just in the one form you want to use it. To set that property, either you fill it in the goApp.Init() event, so you only request once and storer it's response result in that property.

Bye, Olaf.
 
Thanks for the ideas given to that particular issue. I will approach to different options as stated.

Thanks once again

Saif
 
More general speaking, the approach to have a function per prg was recently also promoted by Tamar Granor, here or over at MSDN forums. Instead of lcip = IpInternet() you'd then call DO IpInternet.prg TO lcip

Not necessarily. You can still call it as a function when it's in a same-named program.

I'm one who thinks that one function/procedure per PRG is better. Among my reasons:

1) Only the routines you use end up in the EXE.
2) When working on the code, it's easier to find a routine by its name than in a big file.
3) I've had trouble getting procedure file changes noticed in the IDE. Specifically, if I've built the EXE in that session, I have to delete the EXE to have my changes to the procedure file noticed. (Since I only use procedure files when I inherit applications that have them, it's possible that this is something related to a particular application, but since I see no reason to have procedure files, to me, it's a point against.)

Tamar
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top