【问题标题】:Init.m considerations and good practicesInit.m 注意事项和良好做法
【发布时间】:2011-03-13 23:02:58
【问题描述】:

由于我从未找到(或者可能我从未找到足够多的内容)关于如何管理 init.m 文件的好文章,因此我最终开发了自己的“标准”,但我想知道我做得有多糟糕。

例如,我常用的 init.m 存储在 C:\Documents and Settings\All Users\Application Data\Mathematica\Kernel\init.m (Windows) 中,我使用文本编辑器对其进行编辑。

由于我不希望定义进入全局上下文,因此内容类似于:

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

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

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

我不从 init.m 加载包,因为我想严格控制我加载的内容,所以我在这里只定义了我日常使用的实用程序功能的快捷方式和一些选项。

那么:有没有提到好的做法?实现这种行为的更好方法?有什么注意事项吗?

【问题讨论】:

  • 我的电脑上有几个 init.m 文件。也许有人还可以澄清在不同目录中使用多个 init 文件可以实现什么。我怀疑有多种用途。
  • 在 FrontEnd 目录中编辑 init.m 导致我在 Mathematica 8.0 中忘记了所有 FrontEnd 选项,我想它不应该被触及
  • @Yaro 当我修改 FrontEnd 目录中的 init.m 时,我只收到一条错误消息,并且 Mma 拒绝启动。无论如何,我不确定每个 init.m 应该包含什么:(
  • 我用过一次init.m,但它是用于设置一个包(LevelScheme 的旧形式有一个非标准加载过程)。所以,最佳实践......我很想知道人们如何使用它。
  • @rcollyer 我很想知道人们如何使用它 ...这也许是将我的问题翻译成简单英语的正确方法:D

标签: wolfram-mathematica


【解决方案1】:

首先,我强烈建议不要放置任何重要的init.m,因为这总是会导致几年后您再使用旧的东西时被破坏。将您的自定义设置放在路径上会更好,这样您就可以在每个笔记本的头部快速加载它:这样可以明确说明上下文,您可以轻松更改版本而不会破坏旧内容。

我当前的设置是从Needs["Janus`"] 开始,其中Janus 目录有一个自定义init.m 文件,该文件将目录中的每个文件加载到上下文中。这意味着我可以在每个自己的文件中添加实用程序函数,就像这个 (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[]

这是文件Janus/init.m。请注意,它会打印出加载的扩展的名称,所有这些都是本着保持上下文明确而没有太多麻烦的精神。

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[]]

【讨论】:

  • 我不明白您使用 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"] 的理由不足以描述实际应该加载的内容。一旦我将一个函数添加到我的自定义函数包中,我不会在没有充分理由的情况下删除它。
  • 顺便问一下,如何在内联代码块中获得反引号?
  • @Mr.Wizard:我找到了使用 <code> 的“最简单”的方法。标记,然后用反斜杠转义实际的反引号...
  • @Mr.Wizard:嗯,对我来说,效用函数是一条双向的道路:这些年来我已经放弃了很多,要么是因为弃用,要么是因为我意识到我做事倒退了。为此,我发现文件级原子性使归档更容易。一个关键点是加载器将文件的名称打印到笔记本:如果任何文件已被停用,我可以快速查看Janus/archive/,将实现复制到笔记本中。
【解决方案2】:

我的Kernel/init.m 看起来像这样:

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

WRUtil 包含我所有的小实用程序,并执行考虑到平台和 Mathematica 版本的其他初始化。 MMA_LIB 是一个环境变量,指向一个充满 Mathematica 包的目录。该目录受版本控制,可以由多个 Mathematica 实例共享。我喜欢让init.m 保持简短,以便进入新的 Mathematica 安装就像输入我已经记住的两行代码一样简单——令人惊讶的是,我似乎不得不经常这样做。

【讨论】:

    【解决方案3】:

    我也没有遵循官方的教义,我只能告诉你我是做什么的。

    我的Kernel/init.m 本身不包含任何功能。我用它来:

    • 设置某些选项:$HistoryLengthSetDirectory
    • 做一点清理工作(我不喜欢从空白笔记本开始)
    • 设置我想要的DeclarePackage 呼叫
    • 加载我的自定义函数包

    【讨论】:

    • 是否有理由不在 init.m 中声明自定义函数?
    • @belisarius 我从带有Initialization 单元格的笔记本(.nb)自动生成我的自定义函数包(.m)文件,这对我来说更方便。然而,我希望能够手动编辑我的init.m。这解决了这两个问题。此外,如果我想保留 init.m 的不同版本,我可以更改我的函数而无需同步这些函数。
    猜你喜欢
    • 1970-01-01
    • 2016-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多