From: István Zachar on 20 Jul 2010 03:43 I think you should also protect the public variables of the package at the end to prevent the user to overwrite them. Istvan On Jul 19, 8:10 am, "Nasser M. Abbasi" <n...(a)12000.org> wrote: > On Jul 10, 1:01 am, lynette <xiao...(a)gmail.com> wrote: > > > how to create a mathematica package > > I wrote a small note on this. > > http://12000.org/my_notes/how_to_write_package_in_mathematica/index.htm > > If you find any errors, pls let me know and I'll correct it. > > --Nasser
From: Nasser M. Abbasi on 21 Jul 2010 07:14 On 7/20/2010 12:43 AM, Istv=E1n Zachar wrote: > I think you should also protect the public variables of the package at > the end to prevent the user to overwrite them. > > Istvan When you said the above, I made some experiments, and I think what I need to do in addition to what you said is to also Clear the function nam= e. So, now I have it like this: BeginPackage["foo`"] f::usage = "f[x]" Begin["`Private`"] Unprotect[f]; Clear[f]; f[x_] := Module[{}, x^2]; Protect[f]; End[] EndPackage[] The Unprotect[f] is needed for the case when the package is reloaded again, else one will get an error trying to define something already protected (from the first loading) The Clear[f] is needed, because suppose I had written f=4 Then wanted to load the package Get["foo.m"] Then I would get an error trying to define a function 4[x_]. This is Unprotect[f] does not also Clear[f]. So needed to explicitly do a Clear[f= ]. The last Protect is needed to prevent me from overwriting the name of the function 'f' after I have loaded the package as in: Get["foo.m"] f=4; Does the above seem like the canonical package layout for a simple package? I've also corrected couple of typos (thanks Bill Rowe) and updated the no= te: http://12000.org/my_notes/how_to_write_package_in_mathematica/index.htm If I can improve this more, pls let me know. --Nasser
From: Bill Rowe on 22 Jul 2010 05:43 On 7/21/10 at 7:14 AM, nma(a)12000.org (Nasser M. Abbasi) wrote: >On 7/20/2010 12:43 AM, Istv=E1n Zachar wrote: >>I think you should also protect the public variables of the package >>at the end to prevent the user to overwrite them. >When you said the above, I made some experiments, and I think what I >need to do in addition to what you said is to also Clear the >function nam= e. >So, now I have it like this: >BeginPackage["foo`"] >f::usage = "f[x]" >Begin["`Private`"] >Unprotect[f]; >Clear[f]; >f[x_] := Module[{}, x^2]; >Protect[f]; >End[] >EndPackage[] >The Unprotect[f] is needed for the case when the package is reloaded >again, else one will get an error trying to define something already >protected (from the first loading) I've implemented the following scheme in packages I've written for myself: BeginPackage["foo`"] Unprotect @@ Names["foo`*"]; ClearAll @@ Names["foo`*"]; f::usage = "f[x]" Begin["`Private`"] f[x_] := Module[{}, x^2]; End[] Protect @@ Names["foo`*"]; EndPackage[] This approach saves the need to clear and protect each function individually. It also makes it possible to load the package when it has already been loaded using Get without generating errors. This last is handy when you want to make changes to the package and test those changes. Using Needs won't work for this purpose since Needs will not load a package that is already loaded.
From: Leonid Shifrin on 23 Jul 2010 07:12
On Thu, Jul 22, 2010 at 1:43 PM, Bill Rowe <readnews(a)sbcglobal.net> wrote: > On 7/21/10 at 7:14 AM, nma(a)12000.org (Nasser M. Abbasi) wrote: > > >On 7/20/2010 12:43 AM, Istv=E1n Zachar wrote: > >>I think you should also protect the public variables of the package > >>at the end to prevent the user to overwrite them. > > >When you said the above, I made some experiments, and I think what I > >need to do in addition to what you said is to also Clear the > >function nam= e. > > >So, now I have it like this: > > >BeginPackage["foo`"] > >f::usage = "f[x]" > >Begin["`Private`"] > > >Unprotect[f]; > >Clear[f]; > >f[x_] := Module[{}, x^2]; > >Protect[f]; > > >End[] > >EndPackage[] > > >The Unprotect[f] is needed for the case when the package is reloaded > >again, else one will get an error trying to define something already > >protected (from the first loading) > > I've implemented the following scheme in packages I've written > for myself: > > BeginPackage["foo`"] > > Unprotect @@ Names["foo`*"]; > ClearAll @@ Names["foo`*"]; > > f::usage = "f[x]" > Begin["`Private`"] > > f[x_] := Module[{}, x^2]; > > End[] > Protect @@ Names["foo`*"]; > EndPackage[] > > This approach saves the need to clear and protect each function > individually. It also makes it possible to load the package when > it has already been loaded using Get without generating errors. > This last is handy when you want to make changes to the package > and test those changes. Using Needs won't work for this purpose > since Needs will not load a package that is already loaded. > > > Hi Bill, I've written a package some time ago called PackageManipulations which allows to "remove" or reload a loaded package with functions PackageRemove and PackageReload. It seems to complement your technique. Particularly, after a given package has been "removed", it can be loaded again using Needs. I find it very convenient for interactive package development. It can be found here: http://www.mathprogramming-intro.org/additional_resources.html together with the notebook containing examples of use. Regards, Leonid |