[Date Index] [Thread Index] [Author Index]
Re: contexts,packages,names: again!
> In several recent postings I've asked about separate aspects of getting a > package to work, and I've received quite a few instructive replies. > But when I try to put everything together, I seem to get nowhere. > > Let me try to describe what I need to do in as simple a form as I can > get it without omitting essential aspects. Then perhaps someone can > tell me what will really work! > > The user of the package will evaluate some expressions like: > > CheckMe = "8923"; > f[x_] := g[x, 2]; > g[x_, y_] : = ..... > > Then the user will load my package. Here's what my package must do: > > 0. NOT yet create a new context. > > 1. Test whether the user has given a value to CheckMe, and whether > that value satisfies certain criteria. If not, use Message to issue > appropriate error messages -- still not yet creating a new context. > > 2. Define: > > fname = "f"; > > 3. Test whether the user has created a function named f. If not, use > Message t issue appropriate error messages -- still not yet creating a > new context. > > 4. If, and only if, the tests in 1. and 3. have been satisfied, > actually create a context via BeginPackage[...] and Begin["Private`"] > within which the following steps are performed: > > a. Define various other functions and constants, some of which may > depend on the value of CheckMe. > > b. Using those constants and functions, evaluate the user's f with > arguments some of the constants or functions created in a. (And, of > course, print the results.) > > However, the code here cannot explicitly contain f, but only > refer to it indirectly via its name stored in fname. (This is to > allow as much of the package to be recyclable without in-place editing > each time I need to reconstitute the package for a different function > named by fname.) > > Note that the package does NOT export anything! > > 5. After 4.a and 4.b, use End and EndPackage, together with any other > relevant steps, be sure to leave no trace of any of the names > introduced in the package or any of the functions, etc., defined in > the package's file before the BeginPackage. > > To me, this doesn't sound like it should be at all hard. I'm a very > experienced programmer in several languages in which I've done this > sort of thing. But doing it in Mathematica has me utterly stumped. > That's why I'm asking for such a whole solution -- I simply cannot > make progress on it. > > Thank you for your indulgence. > > -- > Murray Eisenberg Internet: murray at math.umass.edu > Mathematics & Statistics Dept. Voice: 413-545-2859 (W) > University of Massachusetts 413-549-1020 (H) > Amherst, MA 01003 Fax: 413-545-1801 Since I don't entirely understand what you want to do, I can't offer the "whole solution", but I will try to make some useful comments. There are only two reasons to use BeginPackage: 1) To set up a context within which to put exported symbols 2) To get a context added to the $Packages list so that the Needs function will know that it doesn't need to reload the package. Since you have indicated that your package doesn't export any symbols, the first reason doesn't apply. If you want to get your context added to the $Packages list you can do that by entering BeginPackage[...] EndPackage or for that matter by entering Unprotect[$Packages] AppendTo[$Packages, ...] Protect[$Packages] although the latter isn't quite a pretty. All of this seems to be independent of anything else that is going on in your program. The only reason to use Begin[...] is to hide symbols that are local to the package. There are other ways to hide symbols, such as by using local variables in With or Module, or the pattern names that are local to a rule or definition. It sounds like your program works only with symbols in Global` context, and perhaps with symbols that are local to your program. If so, then it doesn't appear that the context system needs to play much of a role in your program at all. Except (as mentioned earlier) for wanting to get your context into the $Packages list, it doesn't seem that Begin and BeginPackage are particularly necessary here. When you say "load a package" do you mean read a file, during which all of the things that you describe here will happen, or do you mean load (and finish loading) a file, *after* which all of the things that you describe here will happen? If you want execution of this program to leave no trace of ever having been loaded, then I am even more convinced that BeginPackage and Begin are irrelevant to this problem. The only purpose of these functions it to set up contexts within which to put symbols, or to make a permanent modification of the $Packages list. If you don't want to leave any trace of having run the program, then you probably don't want to do any of that stuff. Dave Withoff Wolfram Research