10

As I never found (or perhaps I never search for it enough) a good article about how to manage the init.m files, I ended up developing my own "standard", but I wonder how bad I did it.

For example, my usual init.m is stored in C:\Documents and Settings\All Users\Application Data\Mathematica\Kernel\init.m (Windows) and I edit it using a text editor.

As I don't want the definitions to go into the Global context, the content is something like:

(** User Mathematica initialization file **)
Begin["MyInitContext`"];

Cl:=Clear["Global`*"];
(* Other definitions in this Context *)

End[]; (* End Context *)
$ContextPath = Prepend[$ContextPath,"MyInitContext`"];

I don't load packages from the init.m, because I want strict control over what I load, so I only define here shortcuts to utility functions I use on a daily basis and some options.

So: Any references to good practices? Better ways to achieve this kind of behavior? Any caveats?

Dr. belisarius
  • 60,527
  • 15
  • 115
  • 190
  • 1
    There are several init.m files on my computer. Perhaps someone can also clarify what one achieves with several init files in different directories. I suspect there is a range of uses. – DavidC Mar 13 '11 at 23:17
  • Editing `init.m` in FrontEnd directory caused all of my FrontEnd options to be forgotten in Mathematica 8.0, I suppose it shouldn't be touched – Yaroslav Bulatov Mar 14 '11 at 00:53
  • @Yaro When I modify the init.m in the FrontEnd dir, I just receive an error message, and Mma refuses to start. I am not sure what should go in each init.m, anyway :( – Dr. belisarius Mar 14 '11 at 01:40
  • I've used `init.m` once, but it was for setting up a package (older forms of `LevelScheme` had a non-std load procedure). So, best practices ... I'm curious to see how people use it. – rcollyer Mar 14 '11 at 01:53
  • 1
    @rcollyer _I'm curious to see how people use it_ ... that's perhaps the correct way to translate my question to plain English :D – Dr. belisarius Mar 14 '11 at 01:56

3 Answers3

8

Firstly, I would strongly recommend against putting anything significant init.m, since this invariably results in old stuff being broken when you come back to it after a few years. Much better to put your customizations on the path so you can quickly load it at the head of each notebook: That way the context is explicitly stated and you can easily change versions without breaking old stuff.

My current setup is to start with Needs["Janus`"] where the Janus directory has a custom init.m file that loads every file in the directory into the context. This means I can add utility functions in each their own file like this one (clear_cache.m):

ClearCache::usage="ClearCache[f] unsets all numeric-only downvalues of f, \
  see http://stackoverflow.com/questions/5086749"     

Begin["`Private`"];
ClearCache[f_Symbol] := 
  DownValues[f] = DeleteCases[DownValues[f], _?(FreeQ[First[#], Pattern] &)]
End[]

Here is the file Janus/init.m. Note that it prints out the name of the loaded extensions, all in the spirit of keeping the context explicit without too much hassle.

Module[{packageName,packageFileName,fileNames},
  (* $Input is set to Foo.m when evaluating Foo/init.m *)
  If[$Input=="", Print["init.m cannot run interactively"];Abort[]];
  packageName=StringDrop[$Input,-2];
  packageFileName=FindFile[packageName<>"`"];
  If[packageFileName==$Failed, Print["Unable to find package "<>packageName];Abort[]];
  fileNames=Select[
    FileNames["*.m",{DirectoryName@packageFileName},1],
    FileBaseName[#]=!="init"&];
  Print["Loading extensions from "<>DirectoryName@packageFileName<>" to context "<>packageName<>"`:"];
  BeginPackage[packageName<>"`"];
  Do[Print["Loading "<>fn]; Get@fn, {fn,fileNames}];
  EndPackage[]]
Janus
  • 5,421
  • 2
  • 26
  • 37
  • I do not understand your reasoning for using **Needs["Janus`"]** but keeping functions in separate .m files. The only reason I can think for the separate files is so that it is easy remove them selectively, but then your **Needs["Janus`"]** is inadequate to describe what should actually be loaded. Once I have added a function to my custom functions package, I won't delete it without very good reason. – Mr.Wizard Mar 14 '11 at 08:00
  • By the way, how do you get backticks within an inline code block? – Mr.Wizard Mar 14 '11 at 08:02
  • @Mr.Wizard: I've found the "simplest" way to be to use the <code> tag and then escape the actual backtick with a backslash... – Janus Mar 15 '11 at 02:19
  • 1
    @Mr.Wizard: Well, for me the utility functions are a two way street: I've dropped many over the years, either due to deprecation or because I realized that I was doing things backwards. For this, I find file-level atomicity makes the archiving easier. A key point is that the loader prints the names of the files to the notebook: if any of the files have been deactivated I can quickly look through `Janus/archive/` to copy the implementation into the notebook. – Janus Mar 15 '11 at 02:29
7

My Kernel/init.m looks like this:

AppendTo[$Path, Environment["MMA_LIB"]]
Needs["WRUtil`"]

WRUtil contains all of my little utilities and performs other initialization that takes into account the platform and Mathematica version. MMA_LIB is an environment variable that points to a directory full of Mathematica packages. That directory is kept under version control and can be shared by multiple Mathematica instances. I like to keep init.m short so that moving into a new Mathematica installation is as simple as typing two lines that I have committed to memory -- it is surprising how often I seem to have to do this.

WReach
  • 18,098
  • 3
  • 49
  • 93
5

Having also not followed an official doctrine, I can only tell you what I do.

My Kernel/init.m contains no functions itself. I use it to:

  • Set certain options: $HistoryLength SetDirectory etc.
  • Do a little cleanup (I prefer not to start with a blank notebook)
  • Set my desired DeclarePackage calls
  • Load my custom functions package
Mr.Wizard
  • 24,179
  • 5
  • 44
  • 125
  • 2
    Is there a reason for not declaring custom functions in the init.m? – Dr. belisarius Mar 14 '11 at 01:41
  • 2
    @belisarius I generate my custom functions package (.m) file automatically from a Notebook (.nb) with `Initialization` cells, which is much more convenient to me. Yet, I want to be able to edit my `init.m` manually. This addresses both. Also, if I want to keep a different version of `init.m` I can change my functions without having to synchronize these. – Mr.Wizard Mar 14 '11 at 04:18