1 Introduction
1.5 The LFE REPL
1.5.1 Using the REPL
We covered basic REPL usage in the quick start. That's the best place to go for an introduction to using the LFE REPL. Regardless (and for your convenience), we also provide some information about the REPL in the document you are currently reading :-)
1.5.1.1 Starting the REPL
If you don't have LFE installed system-wide, you need to tell it (Erlang,
really) where the LFE .beam
files are. Here are the three ways to start
up LFE in this case:
$ ./bin/lfe -pa ./ebin
or:
$ erl -user lfe_boot -pa /path/to/lfe/ebin
or:
$ erl -pa /path/to/lfe/ebin
followed by this from the Erlang shell:
If you do have LFE installed system-wide, then starting the shell can be done in the ways listed below.
Using the lfe
command. Be sure to change directory to where you have
saved (or cloned) the LFE source code. Then:
$ ./bin/lfe
You can also start the LFE REPL by passing options directly to erl
.
Again, assuming that you have LFE installed system-wide, from any directory you
may do this:
$ erl -user lfe_boot
Also, if you happen to be running an Erlang shell already, you can start the LFE REPL with the following:
1.5.1.2 Running Commands
Once you're in the REPL, it's just a matter of entering code:
Note that you can't define modules, macros, functions or records from the REPL;
you'll have to put those in a module file and compile or slurp
the file
from the REPL. You can, however, use lambda
from the REPL:
Then, using the lambda
you have just defined is as easy as this:
Or, if you want to get nuts:
1.5.1.3 Quitting the REPL
Just as there are multiple ways in which you can start the REPL, there are a
couple ways you can leave it. You can jump into the JCL from the LFE prompt by
hitting ^g and then entering q
:
or you can call the Erlang shell's quit function:
1.5.2 Special Functions
There are some functions specially defined in LFE for use from the REPL. These are listed below with information about their use.
(c File [Options])
- Compile and load an LFE file. Assumes default extension.lfe
.(l Module ...)
- Load modules.(m Module ...)
- Print out module information, if no modules are given then print information about all modules.(ec File [Options])
- Compile and load an Erlang file.(slurp File)
- Slurp in a source LFE file and makes all functions and macros defined in the file available in the shell. Only one file can be slurped at a time and slurping a new file removes all data about the previous one.(unslurp)
- Remove all function and macro definitions except the default ones.(set Pattern Expr)
- Evaluate Expr and match the result with Pattern binding variables in it. These variables can then be used in the shell and also rebound in another set.(: c Command Arg ...)
- All the commands in the Erlang shell's Command Interface Module can be reached in this way.
1.5.3 Special Variables
LFE also provides some convenience variables similar to what Lisp
has defined for
+, ++, +++,
, *, ***,
and
-.
Additionally, LFE also provides the $ENV
variable.
+/++/+++
- The three previous expressions input.*/**/***
- The values of the previous 3 expressions.-
- The current expression input.$ENV
- The current environment (accessible in the REPL as well as in macros).
These probably warrant some examples.
Let's say you had just entered the following in the REPL:
Then you can get the previous expressions you input with the following commands:
Most of us will actually use the arrow keys, thanks to the readline
library. However, the classic, pre-readline
approach is still available,
should you choose to use it.
Similarly, you can get the results returned by using the variabels from the second bullet item. If you're following along in the REPL, go ahead and re-enter the commands we typed above to reset the last three items in your command history. Then do the following:
There's another, called the "dash" varibale. It is bound to the actual expression that is currently being evaluated. Here's an example of this being used:
We've saved one of the more archane special variables to last: $ENV
.
When you first start up a shell, the $ENV
variable holds pristine state
data:
We can define a few variables and then check them out with another display of the environment:
If you slurp
a file in the REPL, your environment will be updated with all
the definitions in that file:
There is, as you might have guessed, much more to that ellided output (for that particular example, nearly all the rest of it is macro definitions).
Making use of $ENV
can be very helpful when debugging include files,
loading Erlang header files, or when creating macros. Furthermore, when spending
a great deal of time in the REPL prototyping code for a project, it can be
quite useful to refresh one's memory as to what functions and variables are
currently available in $ENV
.
Looking at the output for $ENV
can be a bit overwhelming, however. As you
might imagine, there is an easy answer to this: filter it! The following makes
use of the Erlang lists
module as well as patterns in an anonymous
function, both of which will be covered in more detail later:
Now, as one hacks away in the REPL, slurp
ing away at various modules,
getting a list of what's defined in the current environment is a piece of cake:
1.5.4 Getting Out of Trouble
Every once in a while you may find that you do something which causes the REPL to crash, presenting you with something that looks like this:
>
=ERROR REPORT==== 17-Feb-2013::15:39:33 ===
...
You don't have to quit and restart the REPL, if you don't want to! There are a couple of steps that you can take instead.
1.5.4.1 Interrupting a Shell Process
When you get an error as seen above, type ^g
. This will put you into JCL
(Job Control Language) mode. At the JCL prompt, type ?
to see a list of
options:
User switch command
--> ?
c [nn] - connect to job
i [nn] - interrupt job
k [nn] - kill job
j - list all jobs
s [shell] - start local shell
r [node [shell]] - start remote shell
q - quit erlang
? | h - this message
Let's see what's running:
--> j
1* {lfe_shell,start,[]}
Our shell process is still alive, though not responding. Let's interrupt it and then connect to it again:
--> i 1
--> c 1
exception error: function_clause
in (: lists sublist #(error interrupted) 1)
in (lfe_scan string 4)
in (lfe_io scan_and_parse 3)
>
Once we interrupted the job, our error messages were printed to the REPL and we were placed back at the LFE prompt.
1.5.4.2 Starting a New Shell
Sometimes, though, there is no shell process any more. Here's how to start up a new shell process if the one that you're using dies:
--> s lfe_shell
--> j
2* {lfe_shell,start,[]}
--> c 2
LFE Shell V5.9.3.1 (abort with ^G)
>
And you're back up!