В оболочке Erlang, как я могу автоматически читать все заголовки определений моих записей

Это началось с вопроса:

Почти каждый раз, когда я использую оболочку Erlang, мне нужно запустить какую-то команду при запуске оболочки, например. что-то типа

rr("*.hrl").

Или похожие. В настоящее время мне приходится вводить его каждый раз, когда я запускаю оболочку Erlang, и я устаю от этого и все время забываю об этом.

Но на самом деле это был неправильный вопрос! Что я на самом деле хотел сделать, так это прочитать заголовки определения записи в каждом задании оболочки. Не использовать другие встроенные команды оболочки для запуска при запуске. Поэтому я изменил заголовок вопроса, чтобы показать вопрос, как он должен был быть задан.


person Peer Stritzinger    schedule 01.11.2010    source источник


Ответы (3)


Пробуя решение с .erlang, я наткнулся на решение для конкретного использования rr/1:

Из справочной страницы оболочки:

В оболочке есть некоторая поддержка чтения и печати записей. Во время компиляции выражения записи транслируются в выражения кортежа. Во время выполнения неизвестно, действительно ли кортеж представляет собой запись. Определения записей, используемые компилятором, недоступны во время выполнения. Таким образом, чтобы читать синтаксис записи и печатать кортежи как записи, когда это возможно, определения записей должны поддерживаться самой оболочкой. Команды оболочки для чтения, определения, забывания, вывода списка и печати записей описаны ниже. Обратите внимание, что каждое задание имеет собственный набор определений записей. Для упрощения определения записей в модулях 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 ...

Давайте попробуем в оболочке:

$ 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}

→ оболочка знает о записи из foo.hrl

person Peer Stritzinger    schedule 01.11.2010

Файл .erlang оценивается при запуске оболочки, но НЕ оценивается в контексте оболочки. Это означает, что он может содержать только вычисляемые общие выражения, а не команды оболочки. К сожалению, rr() является командой оболочки (она инициализирует локальные данные оболочки для распознавания записей), поэтому ее нельзя использовать в файле .erlang.

Хотя определяемый пользователем модуль user_default, который должен быть предварительно загружен, может включать файлы, содержащие определения записей с использованием -include или -include_lib, эти определения записей будут доступны только для функций, определенных в user_default. user_default — это обычный скомпилированный модуль, и экспортируемые в нем функции вызываются как любые другие функции, поэтому определения записей не будут видны в оболочке. user_default позволяет пользователю определять более сложные функции, которые можно вызывать из оболочки как команды оболочки.

РЕДАКТИРОВАТЬ:

Здесь я был частично не прав. Хотя я был прав относительно того, как оценивается .erlang и как вызываются функции в user_default, я пропустил, как user_default.erl сканируется при запуске оболочки для определения записей, которые затем доступны в оболочке. Спасибо @Peer Stritzinger за указание на это.

person rvirding    schedule 01.11.2010
comment
Вы уверены? Текст с справочной страницы, кажется, говорит об обратном. Чтобы проверить, я создал небольшой тестовый пример (см. ideone.com/4Gau5). Похоже, он работает. . Я что-то пропустил? - person Peer Stritzinger; 02.11.2010
comment
Нет, ты ничего не пропустил. Я проверял код и видел только использование функций в shell_default и user_default и пропустил их сканирование при запуске оболочки. Моя вина. - person rvirding; 02.11.2010

Поместите его в файл с именем .erlang в вашем домашнем каталоге (см. параграф 1.7.1 в http://www.erlang.org/documentation/doc-5.2/doc/getting_started/getting_started.html).

person Alexey Romanov    schedule 01.11.2010
comment
Для примера rr() мне трудно заставить эту работу работать. Во-первых, если я только помещу строку, как указано выше, в .erlang, она не найдет rr/1, и я не знаю, в каком модуле определен rr/1. С другой стороны, я не уверен, что это будет доступно во всех заданиях оболочки. - person Peer Stritzinger; 01.11.2010
comment
@Peer Stritzinger: rr() не определяется как функция; вы можете найти его в stdlib/shell.erl как предложение функции local_func/7. - person Zed; 01.11.2010
comment
@Zed: да, это была моя проблема, и я все равно искал способ автоматического вызова. Финансируйте обходной путь в моем самоответе, и, поскольку я не могу придумать какие-либо другие встроенные псевдофункции оболочки, необходимые при запуске, проблема решается для меня обходным путем. - person Peer Stritzinger; 02.11.2010
comment
Поэтому изменил вопрос, чтобы показать, что я должен был спросить, чтобы сделать это полезным для других... - person Peer Stritzinger; 02.11.2010