【问题标题】:In the Erlang shell, how can I automatically read all my record definition headers在 Erlang shell 中,如何自动读取我所有的记录定义标题
【发布时间】:2011-05-03 13:48:47
【问题描述】:

这开始是一个问题:

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

rr("*.hrl").

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

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

【问题讨论】:

    标签: erlang erlang-shell


    【解决方案1】:

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

    来自 shell 的手册页:

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

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

    to user_default 使 file_info 的定义在 外壳。

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

    文件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的记录

    【讨论】:

      【解决方案2】:

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

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

      编辑:

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

      【讨论】:

      • 你确定吗?手册页中的文字似乎另有说明。为了检查,我设置了一个小测试用例(参见ideone.com/4Gau5),看起来它似乎工作。我错过了什么吗?
      • 不,你没有错过任何东西。我正在检查代码,只看到 shell_defaultuser_default 中的函数的使用,并错过了在 shell 启动时对它们进行的扫描。过失。
      【解决方案3】:

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

      【讨论】:

      • 对于 rr() 的示例,我很难完成这项工作。一方面,如果我只将上述行放在 .erlang 中,它不会找到 rr/1 并且我不知道 rr/1 是在哪个模块中定义的。另一方面,我不确定这是否可用在所有 shell 工作中。
      • @Peer Stitzinger: rr() 未定义为函数;您可以在 stdlib/shell.erl 中找到它作为 local_func/7 函数的子句。
      • @Zed:是的,那是我的问题,我一直在寻找一种自动调用它的方法。在我的自我回答中为解决方法提供资金,并且由于我想不出启动时需要的任何其他 shell 内置伪函数,因此解决方法为我解决了问题。
      • Therfore 更改了问题以显示我应该提出什么要求以使其对其他人有用...
      猜你喜欢
      • 1970-01-01
      • 2016-06-21
      • 2019-07-04
      • 2018-03-22
      • 2013-01-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多