13

这始于问题:

几乎每次我使用 Erlang shell 时,我都想在 shell 启动时运行一些命令,例如

rr("*.hrl").

或类似的。目前我每次启动 Erlang shell 时都必须输入它,我已经厌倦了它并且一直忘记它。

但这实际上是一个错误的问题!因为我真正想做的是在每个 shell 作业中读取我的记录定义标题。不用于其他在启动时运行的 shell 内置命令。因此,我更改了问题标题以显示问题应该如何提出。

4

3 回答 3

17

在尝试解决方案时,.erlang我偶然发现了针对特定rr/1用途的解决方案:

从 shell 的手册页:

在 shell 中有一些对读取和打印记录的支持。在编译期间,记录表达式被转换为元组表达式。在运行时,不知道一个元组是否真的代表一条记录。编译器使用的记录定义在运行时也不可用。因此,为了尽可能读取记录语法并打印元组作为记录,记录定义必须由 shell 本身维护。用于读取、定义、忘记、列出和打印记录的 shell 命令如下所述。请注意,每个作业都有自己的一组记录定义。为方便起见,每次启动新作业时都会读取模块 shell_default 和 user_default(如果已加载)中的记录定义。例如,添加行

  -include_lib("kernel/include/file.hrl").

to user_default 使得 file_info 的定义在 shell 中很容易获得。

为了澄清,我添加了一些示例:

文件foo.hrl

-record(foo, {bar, baz=5}).

文件user_default.erl::

-module(user_default).
-compile(export_all).

-include("foo.hrl").  % include all relevant record definition headers here

 %% more stuff probably ...

让我们在 shell 中尝试一下:

$ erl
Erlang R13B04 (erts-5.7.5) [source] [smp:2:2] [rq:2] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.7.5  (abort with ^G)
1> #foo{}.
#foo{bar = undefined,baz = 5}

→ shell 知道记录来自foo.hrl

于 2010-11-01T20:01:44.117 回答
3

该文件.erlang在 shell 启动时被评估,但它不在shell 的上下文中被评估。这意味着它只能包含被评估的通用表达式,而不是 shell 命令。不幸rr()的是,它是一个 shell 命令(它初始化本地 shell 数据以识别记录),因此它不能在.erlang文件中使用。

user_default虽然必须预加载的用户定义模块可以包含使用-includeor包含记录定义的文件-include_lib,但这些记录定义将仅可用于定义在 中的函数user_defaultuser_default是正常的编译模块,其中的导出函数与任何其他函数一样被调用,因此记录定义在 shell 中将不可见。user_default允许用户定义更复杂的函数,这些函数可以在 shell 中作为 shell 命令调用。

编辑:

我在这里部分错了。虽然我对如何.erlang评估以及如何user_default调用函数是正确的,但我错过了如何user_default.erl在 shell 启动时扫描记录定义,然后这些定义在 shell 中可用。感谢@Peer Stitzinger 指出这一点。

于 2010-11-01T21:45:44.970 回答
0

将它放在.erlang您的主目录中调用的文件中(参见http://www.erlang.org/documentation/doc-5.2/doc/getting_started/getting_started.html中的第 1.7.1 段)。

于 2010-11-01T19:28:31.130 回答