In the Erlang shell, how can I automatically read all my record definition headers
Asked Answered
J

3

13

This started off as the question:

Almost every time when I use the Erlang shell, I'd like to run some command on shell startup, e.g. something like

rr("*.hrl").

Or similar. Currently I have to type it every time I start a Erlang shell and I'm getting tired of it and forget it all the time.

But this was actually the wrong question! For what I actually wanted to do is read my record definition headers in every shell job. Not use for other of the shell built-in commands to run on startup. So I changed the question header to show the question how it should have asked.

Judaize answered 1/11, 2010 at 18:15 Comment(0)
J
17

While trying the solution with .erlang I stumbled upon a solution for the specific rr/1 usage:

From the man-page of shell:

There is some support for reading and printing records in the shell. During compilation record expressions are translated to tuple expres- sions. In runtime it is not known whether a tuple actually represents a record. Nor are the record definitions used by compiler available at runtime. So in order to read the record syntax and print tuples as records when possible, record definitions have to be maintained by the shell itself. The shell commands for reading, defining, forgetting, listing, and printing records are described below. Note that each job has its own set of record definitions. To facilitate matters record definitions in the modules shell_default and user_default (if loaded) are read each time a new job is started. For instance, adding the line

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

to user_default makes the definition of file_info readily available in the shell.

For clarification I add some example:

File foo.hrl:

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

File: user_default.erl:

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

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

 %% more stuff probably ...

Lets try out in the 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}

→ the shell knows about the record from foo.hrl

Judaize answered 1/11, 2010 at 20:1 Comment(0)
N
3

The file .erlang is evaluated when the shell is started, but it is NOT evaluated in the context of the shell. This means that it can only contain general expressions which are evaluated and not shell commands. Unfortunately rr() is a shell command (it initialises local shell data to recognise records) so it can not be used in the .erlang file.

While the user defined module user_default, which must be preloaded, can include files which contain record definitions using -include or -include_lib, these record definitions will then only be available to functions defined within user_default. user_default is normal compiled module and exported functions in it are called as any other functions so the record definitions will not be visible within the shell. user_default allows the user to define more complex functions which can be called from within the shell as shell commands.

EDIT:

I was partially wrong here. While I was correct about how .erlang is evaluated and how the functions in user_default are called I missed how user_default.erl is scanned at shell startup for record definitions which are then available within the shell. Thanks @Peer Stritzinger for pointing this out.

Nematic answered 1/11, 2010 at 21:45 Comment(2)
Are you sure? The text from the manpage seems to say otherwise. To check I set up a small test case (see ideone.com/4Gau5) As it looks it seems to work. Am I missing something?Judaize
No, you haven't missed anything. I was checking the code and only saw the using of functions in shell_default and user_default and missed the scanning done of them at shell startup. Mea culpa.Nematic
P
0

Place it in file called .erlang in your home directory (see paragraph 1.7.1 in http://www.erlang.org/documentation/doc-5.2/doc/getting_started/getting_started.html).

Prince answered 1/11, 2010 at 19:28 Comment(4)
For the example of rr() i have difficulty to make this work. For one if I only put the line as stated above in .erlang it doesn't find rr/1 and I don't know what module rr/1 is defined in. On the other hand I'm not sure this will be available in all shell jobs.Judaize
@Peer Stritzinger: rr() is not defined as a function; you can find it in stdlib/shell.erl as a clause of the local_func/7 function.Heeling
@Zed: yes that was my problem and I was looking for a way to auto call it anyway. Fund the workaround in my self-answer and as I can't think of any other of the shell built-in pseudo-functions needed at startup the problem is solved for me by the workaround.Judaize
Therfore changed the question to show what I should have asked to make this useful for others ...Judaize

© 2022 - 2024 — McMap. All rights reserved.