Erlang Not So Quick Reference
Reserved Words
| after | and | andalso | band | begin | bnot | bor |
| bsl | bsr | bxor | case | catch | cond | div |
| end | fun | if | let | not | of | or |
| orelse | query | receive | rem | try | when | xor |
Numbers
Erlang numbers can either be integers or floats.
- Decimal integer: 1234, 12345678905463789
- integers in the base from 2 to 36 are specified by base#value 2#101010 16#1f.
- ASCII value of the character char specified by $char. $A $]
- Float (double precision): 3.14e-10, .001, 10., 1E3
Arithmetic Expressions
op Expr Expr1 op Expr2
Arithmetic Operators
| op | Description | Argument type |
| + | unary + | number |
| - | unary - | number |
| + | number | |
| - | number | |
| * | number | |
| / | floating point division | number |
| bnot | unary bitwise not | integer |
| div | integer division | integer |
| rem | integer remainder of X/Y | integer |
| band | bitwise and | integer |
| bor | bitwise or integer | |
| bxor | arithmetic bitwise xor | integer |
| bsl | arithmetic bitshift left | integer |
| bsr | bitshift right | integer |
Boolean
Boolean Expressions
op Expr Expr1 op Expr2
Logical Operators
| op | Description |
| not | unary logical not |
| and | logical and |
| or | logical or |
| xor | logical xor |
Atom
An atom is a token starting with a lower case letter containing alphanumeric characters, underscore (_), or @. Atoms can begin or contain any character but then have to be single quoted ('): running, 'FAILED'
Bit Strings and Binaries
A bit string is used to store an area of untyped memory.
Bit Strings are expressed using the bit syntax.
Bit Strings which consists of a number of bits which is evenly divisible by eight are called Binaries
Examples:
1> <<10,20>>. <<10,20>> 2> <<"ABC">>. <<65,66,67>> 1> <<1:1,0:1>>. <<2:2>>
Bit String Comprehensions
Bit string comprehensions are analogous to List Comprehensions. They are used to generate bit strings efficiently and succinctly.
Bit string comprehensions are written with the following syntax:
<< BitString || Qualifier1,...,QualifierN >>
BitString? is a bit string expression, and each Qualifier is either a generator, a bit string generator or a filter.
- A generator is written as:
Pattern <- ListExpr.
ListExpr? must be an expression which evaluates to a list of terms.
- A bit string generator is written as:
BitstringPattern <= BitStringExpr.
BitStringExpr? must be an expression which evaluates to a bitstring.
- A filter is an expression which evaluates to true or false.
The variables in the generator patterns shadow variables in the function clause surrounding the bit string comprehensions.
A bit string comprehension returns a bit string, which is created by concatenating the results of evaluating BitString? for each combination of bit string generator elements for which all filters are true.
Example:
1> << << X*2 >> || <<X>> <= << 1,2,3 >> >>. <<2,4,6>>
Reference
A reference is a term which is unique in an Erlang runtime system, created by calling make_ref/0.
Fun
a fun is an anonymous function ( a lambda in functional programming): For instance you can define Fun1 = fun (X) -> X+1 end. and use it like Fun1(10).
Expression
fun
(Pattern11,...,Pattern1N) [when GuardSeq1] ->
Body1;
...;
(PatternK1,...,PatternKN) [when GuardSeqK] ->
BodyK
end
A fun expression begins with the keyword fun and ends with the keyword end. Between them should be a function declaration, similar to a regular function declaration, except that no function name is specified.
Variables in a fun head shadow variables in the function clause surrounding the fun expression, and variables bound in a fun body are local to the fun body.
The return value of the expression is the resulting fun.
Examples:
1> Fun1 = fun (X) -> X+1 end. #Fun<erl_eval.6.39074546> 2> Fun1(2). 3 3> Fun2 = fun (X) when X>=5 -> gt; (X) -> lt end. #Fun<erl_eval.6.39074546> 4> Fun2(7). gt
The following fun expressions are also allowed:
fun Name/Arity fun Module:Name/Arity
In Name/Arity, Name is an atom and Arity is an integer. Name/Arity must specify an existing local function. The expression is syntactic sugar for:
fun (Arg1,...,ArgN) -> Name(Arg1,...,ArgN) end
In Module:Name/Arity, Module and Name are atoms and Arity is an integer. A fun defined in this way will refer to the function Name with arity Arity in the latest version of module Module.
When applied to a number N of arguments, a tuple {Module,FunctionName?} is interpreted as a fun, referring to the function FunctionName? with arity N in the module Module. The function must be exported. This usage is deprecated. See Function Calls for an example.
Port Identifier
A port identifier is a special idetifier that preresents an erlang port created when a port is opened by open_port/2.
Pid
A pid is a process identifier, pid, identifies a process created by spawn/1,2,3,4, spawn_link/1,2,3,4 and spawn_opt/4.
Bit Strings and Binaries
A bit string is used to represent raw bytes, called Binaries: <<10,20>>, <<"ABC">>, <<1:1,0:1>> Bit Strings are expressed using the bit syntax.
Tuple
Compound data type with a fixed number of terms: {adam,24,{july,29}}.
When comparing Tuples they are ordered by size, two tuples with the same size are then compared element by element.
= List ==
Compound data type with a variable number of terms, defined by [head|tail] or [head, element1,...] : [], [c|[]], [b|[c|[]]]
Lists are compared element by element.
List Operations
| ++ | The list concatenation operator ++ appends its second argument to its first and returns the resulting list. | [1,2,3]++[4,5] -> [1,2,3,4,5] |
| -- | The list subtraction operator -- produces a list which is a copy of the first argument, subjected to the following procedure: for each element in the second argument, the first occurrence of this element (if any) is removed. | [1,2,3,2,1,2]--[2,1,2] -> [3,1,2] |
List Comprehensions
List comprehensions are a feature of many modern functional programming languages. Subject to certain rules, they provide a succinct notation for generating elements in a list.
List comprehensions are analogous to set comprehensions in Zermelo-Frankel set theory and are called ZF expressions in Miranda. They are analogous to the setof and findall predicates in Prolog.
List comprehensions are written with the following syntax:
[Expr || Qualifier1,...,QualifierN]
Expr is an arbitrary expression, and each Qualifier is either a generator or a filter.
- A generator is written as:
Pattern <- ListExpr?.
ListExpr? must be an expression which evaluates to a list of terms.
- A bit string generator is written as:
BitStringExpr? must be an expression which evaluates to a bitstring.
- A filter is an expression which evaluates to true or false.
The variables in the generator patterns shadow variables in the function clause surrounding the list comprehensions.
A list comprehension returns a list, where the elements are the result of evaluating Expr for each combination of generator list elements and bit string generator elements for which all filters are true.
Example:
1> [X*2 || X <- [1,2,3]].
[2,4,6]
String
Strings literals are double quoted ("),but are infact lists of characters. At compile time adjacent string literals are concatenated into one. Within strings and quoted atoms, the following escape sequences are recognized:
| Recognized Escape Sequences. | |
| Sequence | Description |
| \b | backspace |
| \d | delete |
| \e | escape |
| \f | form feed |
| \ | newline |
| \r | carriage return |
| \s | space |
| \t | tab |
| \v | vertical tab |
| \XYZ, \YZ, \Z | character with octal representation XYZ, YZ or Z |
| \a...\z | |
| \A...\Z | control A to control Z |
| \' | single quote |
| \" | double quote |
| \\ | backslash |
Expressions
Terms
A term in an expression is an atom, integer, float, string, list or tuple. Its return value is itself.
Variables
Variables start with an uppercase letter or underscore (_) and may contain alphanumeric characters, underscore and @. Examples: X, Name1, PhoneNumber?, Phone_number, _, _Height Variables are bound to values using pattern matching. Variables are immutable. The anonymous variable is denoted by underscore (_) and can be used as a dummy variable: [H|_] = [1,2,3] A variable is an expression. If a variable is bound to a value, the return value is this value. Unbound variables are only allowed in patterns. The scope for a variable is its function clause. Variables bound in a branch of an if, case, or receive expression must be bound in all branches to have a value outside the expression, otherwise they will be regarded as 'unsafe' outside the expression.
Pattern
A pattern is term that may contain unbound variables. Patterns are allowed in clause heads, case and receive expressions, and match expressions: Name1, [H|T], {error,Reason}
Match
Pattern = Expression
If the matching succeeds, any unbound variable in the Pattern becomes bound and the value of Expression is returned. If the matching fails, a badmatch run-time error will be raised:
1> {A, B} = {answer, 42}.
{answer,42}
2> A.
answer
3> {C, D} = [1, 2].
** exited: {{badmatch,[1,2]},[{erl_eval,expr,3}]} **
Operator Precedence
Operator precedence in falling priority:
| Operator Precedence. | |
| : | |
| # | |
| Unary + - bnot not | |
| / * div rem band and | Left associative |
| + - bor bxor bsl bsr or xor | Left associative |
| ++ -- | Right associative |
| == /= =< < >= > =:= =/= | - |
| andalso | |
| orelse | |
| = ! | Right associative |
| catch |
What about ","
When evaluating an expression, the operator with the highest priority is evaluated first. Operators with the same priority are evaluated according to their associativity. Example: The left associative arithmetic operators are evaluated left to right:
6 + 5 * 4 - 3 / 2 evaluates to 6 + 20 - 1.5 evaluates to 26 - 1.5 evaluates to 24.5
Term Comparisons
Expr1 op Expr2
| op | Description |
| == | equal to |
| /= | not equal to |
| =< | less than or equal to |
| < | less than |
| >= | greater than or equal to |
| > | greater than |
| =:= | exactly equal to |
| =/= | exactly not equal to |
The arguments may be of different data types. The following order is defined:
number < atom < reference < fun < port < pid < tuple < list < bit string
Lists are compared element by element. Tuples are ordered by size, two tuples with the same size are compared element by element.
All comparison operators except =:= and =/= are of type coerce: When comparing an integer and a float, the integer is first converted to a float. In the case of =:= and =/=, there is no type conversion.
Returns the Boolean value of the expression, true or false.
Arithmetic Operators
| op | Description | Argument type | Example |
| + | unary + | number | |
| - | unary - | number | |
| + | number | ||
| - | number | ||
| * | number | ||
| / | floating point division | number | |
| bnot | unary bitwise not | integer | |
| div | integer division | integer | |
| rem | integer remainder of X/Y | integer | |
| band | bitwise and | integer | |
| bor | bitwise or | integer | |
| bxor | arithmetic bitwise xor | integer | |
| bsl | arithmetic bitshift left | integer | |
| bsr | bitshift right | integer |
Boolean Expressions
| op | Description | |
| not | unary logical not | |
| and | logical and | |
| or | logical or | |
| xor | logical xor | |
| orelse | Short-Circuit or | |
| andalso | Short-Circuit and |
If
if
GuardSeq1 ->
Body1;
...;
GuardSeqN ->
BodyN
end
The branches of an if-expression are scanned sequentially until a guard sequence GuardSeq? which evaluates to true is found. Then the corresponding Body (sequence of expressions separated by ',') is evaluated.
The return value of Body is the return value of the if expression.
If no guard sequence is true, an if_clause run-time error will occur. If necessary, the guard expression true can be used in the last branch, as that guard sequence is always true.
Example:
is_greater_than(X, Y) ->
if
X>Y ->
true;
true -> % works as an 'else' branch
false
end
Case
case Expr of
Pattern1 [when GuardSeq1] ->
Body1;
...;
PatternN [when GuardSeqN] ->
BodyN
end
The expression Expr is evaluated and the patterns Pattern are sequentially matched against the result. If a match succeeds and the optional guard sequence GuardSeq? is true, the corresponding Body is evaluated.
The return value of Body is the return value of the case expression.
If there is no matching pattern with a true guard sequence, a case_clause run-time error will occur.
Example:
is_valid_signal(Signal) ->
case Signal of
{signal, _What, _From, _To} ->
true;
{signal, _What, _To} ->
true;
_Else ->
false
end.
Send
Expr1 ! Expr2
Sends the value of Expr2 as a message to the process specified by Expr1. The value of Expr2 is also the return value of the expression.
Expr1 must evaluate to a pid, a registered name (atom) or a tuple {Name,Node}, where Name is an atom and Node a node name, also an atom.
- If Expr1 evaluates to a name, but this name is not registered, a badarg run-time error will occur.
- Sending a message to a pid never fails, even if the pid identifies a non-existing process.
- Distributed message sending, that is if Expr1 evaluates to a tuple {Name,Node} (or a pid located at another node), also never fails.
Receive
receive
Pattern1 [when GuardSeq1] ->
Body1;
...;
PatternN [when GuardSeqN] ->
BodyN
end
Receives messages sent to the process using the send operator (!). The patterns Pattern are sequentially matched against the first message in time order in the mailbox, then the second, and so on. If a match succeeds and the optional guard sequence GuardSeq? is true, the corresponding Body is evaluated. The matching message is consumed, that is removed from the mailbox, while any other messages in the mailbox remain unchanged.
The return value of Body is the return value of the receive expression.
receive never fails. Execution is suspended, possibly indefinitely, until a message arrives that does match one of the patterns and with a true guard sequence.
Example:
wait_for_onhook() ->
receive
onhook ->
disconnect(),
idle();
{connect, B} ->
B ! {busy, self()},
wait_for_onhook()
end.
It is possible to augment the receive expression with a timeout:
receive
Pattern1 [when GuardSeq1] ->
Body1;
...;
PatternN [when GuardSeqN] ->
BodyN
after
ExprT ->
BodyT
end
ExprT should evaluate to an integer. The highest allowed value is 16#ffffffff, that is, the value must fit in 32 bits. receive..after works exactly as receive, except that if no matching message has arrived within ExprT milliseconds, then BodyT is evaluated instead and its return value becomes the return value of the receive..after expression.
Example:
wait_for_onhook() ->
receive
onhook ->
disconnect(),
idle();
{connect, B} ->
B ! {busy, self()},
wait_for_onhook()
after
60000 ->
disconnect(),
error()
end.
It is legal to use a receive..after expression with no branches:
receive
after
ExprT ->
BodyT
end
This construction will not consume any messages, only suspend execution in the process for ExprT milliseconds and can be used to implement simple timers.
Example:
timer() ->
spawn(m, timer, [self()]).
timer(Pid) ->
receive
after
5000 ->
Pid ! timeout
end.
There are two special cases for the timeout value ExprT:
infinity
The process should wait indefinitely for a matching message -- this is the same as not using a timeout. Can be useful for timeout values that are calculated at run-time. 0 If there is no matching message in the mailbox, the timeout will occur immediately.
Catch and Throw
catch Expr
Returns the value of Expr unless an exception occurs during the evaluation. In that case, the exception is caught. For exceptions of class error, that is run-time errors: {'EXIT',{Reason,Stack}} is returned. For exceptions of class exit, that is the code called exit(Term): {'EXIT',Term} is returned. For exceptions of class throw, that is the code called throw(Term): Term is returned.
Reason depends on the type of error that occurred, and Stack is the stack of recent function calls, see Errors and Error Handling.
Examples:
1> catch 1+2.
3
2> catch 1+a.
{'EXIT',{badarith,[...]}}
Note that catch has low precedence and catch subexpressions often needs to be enclosed in a block expression or in parenthesis:
3> A = catch 1+2. ** 1: syntax error before: 'catch' ** 4> A = (catch 1+2). 3
The BIF throw(Any) can be used for non-local return from a function. It must be evaluated within a catch, which will return the value Any. Example:
5> catch throw(hello). hello
If throw/1 is not evaluated within a catch, a nocatch run-time error will occur.
Try
try Exprs
catch
[Class1:]ExceptionPattern1 [when ExceptionGuardSeq1] ->
ExceptionBody1;
[ClassN:]ExceptionPatternN [when ExceptionGuardSeqN] ->
ExceptionBodyN
end
This is an enhancement of catch that appeared in Erlang 5.4/OTP-R10B. It gives the possibility do distinguish between different exception classes, and to choose to handle only the desired ones, passing the others on to an enclosing try or catch or to default error handling.
Note that although the keyword catch is used in the try expression, there is not a catch expression within the try expression.
Returns the value of Exprs (a sequence of expressions Expr1, ..., ExprN) unless an exception occurs during the evaluation. In that case the exception is caught and the patterns ExceptionPattern? with the right exception class Class are sequentially matched against the caught exception. An omitted Class is shorthand for throw. If a match succeeds and the optional guard sequence ExceptionGuardSeq? is true, the corresponding ExceptionBody? is evaluated to become the return value.
If an exception occurs during evaluation of Exprs but there is no matching ExceptionPattern? of the right Class with a true guard sequence, the exception is passed on as if Exprs had not been enclosed in a try expression.
If an exception occurs during evaluation of ExceptionBody? it is not caught.
The try expression can have an of section:
try Exprs of
Pattern1 [when GuardSeq1] ->
Body1;
...;
PatternN [when GuardSeqN] ->
BodyN
catch
[Class1:]ExceptionPattern1 [when ExceptionGuardSeq1] ->
ExceptionBody1;
...;
[ClassN:]ExceptionPatternN [when ExceptionGuardSeqN] ->
ExceptionBodyN
end
If the evaluation of Exprs succeeds without an exception, the patterns Pattern are sequentially matched against the result in the same way as for a case expression, except that if the matching fails, a try_clause run-time error will occur.
An exception occurring during the evaluation of Body is not caught.
The try expression can also be augmented with an after section, intended to be used for cleanup with side effects:
try Exprs of
Pattern1 [when GuardSeq1] ->
Body1;
...;
PatternN [when GuardSeqN] ->
BodyN
catch
[Class1:]ExceptionPattern1 [when ExceptionGuardSeq1] ->
ExceptionBody1;
...;
[ClassN:]ExceptionPatternN [when ExceptionGuardSeqN] ->
ExceptionBodyN
after
AfterBody
end
AfterBody? is evaluated after either Body or ExceptionBody? no matter which one. The evaluated value of AfterBody? is lost; the return value of the try expression is the same with an after section as without.
Even if an exception occurs during evaluation of Body or ExceptionBody?, AfterBody? is evaluated. In this case the exception is passed on after AfterBody? has been evaluated, so the exception from the try expression is the same with an after section as without.
If an exception occurs during evaluation of AfterBody? itself it is not caught, so if AfterBody? is evaluated after an exception in Exprs, Body or ExceptionBody?, that exception is lost and masked by the exception in AfterBody?.
The of, catch and after sections are all optional, as long as there is at least a catch or an after section, so the following are valid try expressions:
try Exprs of
Pattern when GuardSeq ->
Body
after
AfterBody
end
try Exprs
catch
ExpressionPattern ->
ExpressionBody
after
AfterBody
end
try Exprs after AfterBody end
Example of using after, this code will close the file even in the event of exceptions in file:read/2 or in binary_to_term/1, and exceptions will be the same as without the try...after...end expression:
termize_file(Name) ->
{ok,F} = file:open(Name, [read,binary]),
try
{ok,Bin} = file:read(F, 1024*1024),
binary_to_term(Bin)
after
file:close(F)
end.
Example: Using try to emulate catch Expr.
try Expr
catch
throw:Term -> Term;
exit:Reason -> {'EXIT',Reason}
error:Reason -> {'EXIT',{Reason,erlang:get_stacktrace()}}
end
Parenthesized Expressions
(Expr)
Parenthesized expressions are useful to override operator precedences, for example in arithmetic expressions:
1> 1 + 2 * 3. 7 2> (1 + 2) * 3. 9
Block Expressions
begin Expr1, ..., ExprN end
Block expressions provide a way to group a sequence of expressions, similar to a clause body. The return value is the value of the last expression ExprN.
Guard Sequences
A guard sequence is a sequence of guards, separated by semicolon (;). The guard sequence is true if at least one of the guards is true.
Guard1;...;GuardK
A guard is a sequence of guard expressions, separated by comma (,). The guard is true if all guard expressions evaluate to true.
GuardExpr1,...,GuardExprN
The set of valid guard expressions (sometimes called guard tests) is a subset of the set of valid Erlang expressions. The reason for restricting the set of valid expressions is that evaluation of a guard expression must be guaranteed to be free of side effects. Valid guard expressions are:
- the atom true,
- other constants (terms and bound variables), all regarded as false,
- calls to the BIFs specified below,
- term comparisons,
- arithmetic expressions,
- boolean expressions, and
- short-circuit boolean expressions.
Type Test BIFs.
| is_atom/1 |
| is_binary/1 |
| is_constant/1 |
| is_float/1 |
| is_function/1 |
| is_function/2 |
| is_integer/1 |
| is_list/1 |
| is_number/1 |
| is_pid/1 |
| is_port/1 |
| is_reference/1 |
| is_tuple/1 |
| is_record/2 |
| is_record/3 |
Note that each type test BIF has an older equivalent, without the is_ prefix. These old BIFs are retained for backwards compatibility only and should not be used in new code. They are also only allowed at top level. For example, they are not allowed in boolean expressions in guards.
| abs(Number) |
| element(N, Tuple) |
| float(Term) |
| hd(List) |
| length(List) |
| node() |
| node(Pid|Ref|Port) |
| round(Number) |
| self() |
| size(Tuple|Binary) |
| tl(List) |
| trunc(Number) |
Other BIFs Allowed in Guard Expressions.
Macros
Predefined Macros
The following macros are predefined:
| ?MODULE | The name of the current module. |
| ?MODULE_STRING. | The name of the current module, as a string. |
| ?FILE. | The file name of the current module. |
| ?LINE. | The current line number. |
| ?MACHINE. | The machine name, 'BEAM'. |
Defining and Using Macros
A macro is defined the following way:
-define(Const, Replacement). -define(Func(Var1,...,VarN), Replacement).
A macro definition can be placed anywhere among the attributes and function declarations of a module, but the definition must come before any usage of the macro.
If a macro is used in several modules, it is recommended that the macro definition is placed in an include file.
A macro is used the following way:
?Const ?Func(Arg1,...,ArgN)
Macros are expanded during compilation. A simple macro ?Const will be replaced with Replacement. Example:
-define(TIMEOUT, 200).
...
call(Request) ->
server:call(refserver, Request, ?TIMEOUT).
This will be expanded to:
call(Request) ->
server:call(refserver, Request, 200).
A macro ?Func(Arg1,...,ArgN) will be replaced with Replacement, where all occurrences of a variable Var from the macro definition are replaced with the corresponding argument Arg. Example:
-define(MACRO1(X, Y), {a, X, b, Y}).
...
bar(X) ->
?MACRO1(a, b),
?MACRO1(X, 123)
This will be expanded to:
bar(X) ->
{a,a,b,b},
{a,X,b,123}.
It is good programming practice, but not mandatory, to ensure that a macro definition is a valid Erlang syntactic form.
To view the result of macro expansion, a module can be compiled with the 'P' option. compile:file(File, ['P']). This produces a listing of the parsed code after preprocessing and parse transforms, in the file File.P.
Flow Control in Macros
The following macro directives are supplied:
| -undef(Macro). | Causes the macro to behave as if it had never been defined. |
| -ifdef(Macro). | Evaluate the following lines only if Macro is defined. |
| -ifndef(Macro). | Evaluate the following lines only if Macro is not defined. |
| -else. | Only allowed after an ifdef or ifndef directive. If that condition was false, the lines following else are evaluated instead. |
| -endif. | Specifies the end of an ifdef or ifndef directive. |
Example:
-module(m).
...
-ifdef(debug).
-define(LOG(X), io:format("{~p,~p}: ~p~n", [?MODULE,?LINE,X])).
-else.
-define(LOG(X), true).
-endif.
...
When trace output is desired, debug should be defined when the module m is compiled:
% erlc -Ddebug m.erl
or
1> c(m, {d, debug}).
{ok,m}
?LOG(Arg) will then expand to a call to io:format/2 and provide the user with some simple trace output.
Stringifying Macro Arguments
The construction ??Arg, where Arg is a macro argument, will be expanded to a string containing the tokens of the argument. This is similar to the #arg stringifying construction in C.
The feature was added in Erlang 5.0/OTP R7.
Example:
-define(TESTCALL(Call), io:format("Call ~s: ~w~n", [??Call, Call])).
?TESTCALL(myfunction(1,2)),
?TESTCALL(you:function(2,1)).
results in
io:format("Call ~s: ~w~n",["myfunction ( 1 , 2 )",m:myfunction(1,2)]),
io:format("Call ~s: ~w~n",["you : function ( 2 , 1 )",you:function(2,1)]).
That is, a trace output with both the function called and the resulting value.
Records
A record is a data structure for storing a fixed number of elements. It has named fields and is similar to a struct in C. Record expressions are translated to tuple expressions during compilation. Therefore, record expressions are not understood by the shell unless special actions are taken. See shell(3) for details.
Defining Records
A record definition consists of the name of the record, followed by the field names of the record. Record and field names must be atoms. Each field can be given an optional default value. If no default value is supplied, undefined will be used.
-record(Name, {Field1 [= Value1],
...
FieldN [= ValueN]}).
A record definition can be placed anywhere among the attributes and function declarations of a module, but the definition must come before any usage of the record.
If a record is used in several modules, it is recommended that the record definition is placed in an include file.
Creating Records
The following expression creates a new Name record where the value of each field FieldI is the value of evaluating the corresponding expression ExprI:
#Name{Field1=Expr1,...,FieldK=ExprK}
The fields may be in any order, not necessarily the same order as in the record definition, and fields can be omitted. Omitted fields will get their respective default value instead.
If several fields should be assigned the same value, the following construction can be used:
#Name{Field1=Expr1,...,FieldK=ExprK, _=ExprL}
Omitted fields will then get the value of evaluating ExprL instead of their default values. This feature was added in Erlang 5.1/OTP R8 and is primarily intended to be used to create patterns for ETS and Mnesia match functions. Example:
-record(person, {name, phone, address}).
...
lookup(Name, Tab) ->
ets:match_object(Tab, #person{name=Name, _='_'}).
Accessing Record Fields
Expr#Name.Field
Returns the value of the specified field. Expr should evaluate to a Name record.
The following expression returns the position of the specified field in the tuple representation of the record:
#Name.Field
Example:
-record(person, {name, phone, address}).
...
lookup(Name, List) ->
lists:keysearch(Name, #person.name, List).
Updating Records
Expr#Name{Field1=Expr1,...,FieldK=ExprK}
Expr should evaluate to a Name record. Returns a copy of this record, with the value of each specified field FieldI changed to the value of evaluating the corresponding expression ExprI. All other fields retain their old values.
Records in Guards
Since record expressions are expanded to tuple expressions, creating records and accessing record fields are allowed in guards. However all subexpressions, for example for field initiations, must of course be valid guard expressions as well. Examples:
handle(Msg, State) when Msg==#msg{to=void, no=3} ->
...
handle(Msg, State) when State#state.running==true ->
...
There is also a type test BIF is_record(Term, RecordTag?). Example:
is_person(P) when is_record(P, person) ->
true;
is_person(_P) ->
false.
Records in Patterns
A pattern that will match a certain record is created the same way as a record is created:
#Name{Field1=Expr1,...,FieldK=ExprK}
In this case, one or more of Expr1...ExprK may be unbound variables.
Internal Representation of Records
Record expressions are translated to tuple expressions during compilation. A record defined as
-record(Name, {Field1,...,FieldN}).
is internally represented by the tuple
{Name,Value1,...,ValueN}
where each ValueI is the default value for FieldI.
To each module using records, a pseudo function is added during compilation to obtain information about records:
record_info(fields, Record) -> [Field] record_info(size, Record) -> Size
Size is the size of the tuple representation, that is one more than the number of fields.
Errors and Error Handling
Terminology
Errors can roughly be divided into four different types:
- Compile-time errors
- Logical errors
- Run-time errors
- Generated errors
A compile-time error, for example a syntax error, should not cause much trouble as it is caught by the compiler.
A logical error is when a program does not behave as intended, but does not crash. An example could be that nothing happens when a button in a graphical user interface is clicked.
A run-time error is when a crash occurs. An example could be when an operator is applied to arguments of the wrong type. The Erlang programming language has built-in features for handling of run-time errors.
A run-time error can also be emulated by calling erlang:error(Reason), erlang:error(Reason, Args) (those appeared in Erlang 5.4/OTP-R10), erlang:fault(Reason) or erlang:fault(Reason, Args) (old equivalents).
A run-time error is another name for an exception of class error.
A generated error is when the code itself calls exit/1 or throw/1. Note that emulated run-time errors are not denoted as generated errors here.
Generated errors are exceptions of classes exit and throw.
When a run-time error or generated error occurs in Erlang, execution for the process which evaluated the erroneous expression is stopped. This is referred to as a failure, that execution or evaluation fails, or that the process fails, terminates or exits. Note that a process may terminate/exit for other reasons than a failure.
A process that terminates will emit an exit signal with an exit reason that says something about which error has occurred. Normally, some information about the error will be printed to the terminal.
=== Exceptions ==
Exceptions are run-time errors or generated errors and are of three different classes, with different origins. The try expression (appeared in Erlang 5.4/OTP-R10B) can distinguish between the different classes, whereas the catch expression can not. They are described in the Expressions chapter.
| Exception Classes. | |
| Class | Origin |
| error | Run-time error for example 1+a, or the process called erlang:error/1,2 (appeared in Erlang 5.4/OTP-R10B) or erlang:fault/1,2 (old equivalent) |
| exit | The process called exit/1 |
| throw | The process called throw/1 |
An exception consists of its class, an exit reason (the Exit Reason), and a stack trace (that aids in finding the code location of the exception).
The stack trace can be retrieved using erlang:get_stacktrace/0 (new in Erlang 5.4/OTP-R10B from within a try expression, and is returned for exceptions of class error from a catch expression.
An exception of class error is also known as a run-time error.
Handling of Run-Time Errors in Erlang
- Error Handling Within Processes
It is possible to prevent run-time errors and other exceptions from causing the process to terminate by using catch or try, see the Expressions chapter about Catch and Try.
- Error Handling Between Processes
Processes can monitor other processes and detect process terminations, see the Processes chapter.
Exit Reasons
When a run-time error occurs, that is an exception of class error, the exit reason is a tuple {Reason,Stack}. Reason is a term indicating the type of error:
| Exit Reasons. | |
| Reason | Type of error |
| badarg | Bad argument. The argument is of wrong data type, or is otherwise badly formed. |
| badarith | Bad argument in an arithmetic expression. |
| {badmatch,V} | Evaluation of a match expression failed. The value V did not match. |
| function_clause | No matching function clause is found when evaluating a function call. |
| {case_clause,V} | No matching branch is found when evaluating a case expression. The value V did not match. |
| if_clause | No true branch is found when evaluating an if expression. |
| {try_clause,V} | No matching branch is found when evaluating the of-section of a try expression. The value V did not match. |
| undef | The function cannot be found when evaluating a function call. |
| {badfun,F} | There is something wrong with a fun F. |
| {badarity,F} | A fun is applied to the wrong number of arguments. F describes the fun and the arguments. |
| timeout_value | The timeout value in a receive..after expression is evaluated to something else than an integer or infinity. |
| noproc | Trying to link to a non-existing process. |
| {nocatch,V} | Trying to evaluate a throw outside a catch. V is the thrown term. |
| system_limit | A system limit has been reached. See Efficiency Guide for information about system limits. |
Stack is the stack of function calls being evaluated when the error occurred, given as a list of tuples {Module,Name,Arity} with the most recent function call first. The most recent function call tuple may in some cases be {Module,Name,[Arg]}.
Processes
Processes
Erlang is designed for massive concurrency. Erlang processes are light-weight (grow and shrink dynamically) with small memory footprint, fast to create and terminate and the scheduling overhead is low. 10.2 Process Creation
A process is created by calling spawn:
spawn(Module, Name, Args) -> pid()
Module = Name = atom()
Args = [Arg1,...,ArgN]
ArgI = term()
spawn creates a new process and returns the pid.
The new process will start executing in Module:Name(Arg1,...,ArgN) where the arguments is the elements of the (possible empty) Args argument list.
There exist a number of other spawn BIFs, for example spawn/4 for spawning a process at another node.
Registered Processes
Besides addressing a process by using its pid, there are also BIFs for registering a process under a name. The name must be an atom and is automatically unregistered if the process terminates:
| Name | Registration BIFs. |
| register(Name, Pid) | Associates the name Name, an atom, with the process Pid. |
| registered() | Returns a list of names which have been registered usingregister/2. |
| whereis(Name) | Returns the pid registered under Name, orundefinedif the name is not registered. |
Process Termination
When a process terminates, it always terminates with an exit reason. The reason may be any term.
A process is said to terminate normally, if the exit reason is the atom normal. A process with no more code to execute terminates normally.
A process terminates with exit reason {Reason,Stack} when a run-time error occurs. See Error and Error Handling.
A process can terminate itself by calling one of the BIFs exit(Reason), erlang:error(Reason), erlang:error(Reason, Args), erlang:fault(Reason) or erlang:fault(Reason, Args). The process then terminates with reason Reason for exit/1 or {Reason,Stack} for the others.
A process may also be terminated if it receives an exit signal with another exit reason than normal, see Error Handling below.
Message Sending
Processes communicate by sending and receiving messages. Messages are sent by using the send operator ! and received by calling receive.
Message sending is asynchronous and safe, the message is guaranteed to eventually reach the recipient, provided that the recipient exists.
Links
Two processes can be linked to each other. A link between two processes Pid1 and Pid2 is created by Pid1 calling the BIF link(Pid2) (or vice versa). There also exists a number a spawn_link BIFs, which spawns and links to a process in one operation.
Links are bidirectional and there can only be one link between two processes. Repeated calls to link(Pid) have no effect.
A link can be removed by calling the BIF unlink(Pid).
Links are used to monitor the behaviour of other processes, see Error Handling below.
Error Handling
Erlang has a built-in feature for error handling between processes. Terminating processes will emit exit signals to all linked processes, which may terminate as well or handle the exit in some way. This feature can be used to build hierarchical program structures where some processes are supervising other processes, for example restarting them if they terminate abnormally.
Refer to OTP Design Principles for more information about OTP supervision trees, which uses this feature.
Emitting Exit Signals
When a process terminates, it will terminate with an exit reason as explained in Process Termination above. This exit reason is emitted in an exit signal to all linked processes.
A process can also call the function exit(Pid,Reason). This will result in an exit signal with exit reason Reason being emitted to Pid, but does not affect the calling process.
Receiving Exit Signals
The default behaviour when a process receives an exit signal with an exit reason other than normal, is to terminate and in turn emit exit signals with the same exit reason to its linked processes. An exit signal with reason normal is ignored.
A process can be set to trap exit signals by calling:
{{ process_flag(trap_exit, true) }}
When a process is trapping exits, it will not terminate when an exit signal is received. Instead, the signal is transformed into a message {'EXIT',FromPid?,Reason} which is put into the mailbox of the process just like a regular message.
An exception to the above is if the exit reason is kill, that is if exit(Pid,kill) has been called. This will unconditionally terminate the process, regardless of if it is trapping exit signals or not.
Monitors
An alternative to links are monitors. A process Pid1 can create a monitor for Pid2 by calling the BIF erlang:monitor(process, Pid2). The function returns a reference Ref.
If Pid2 terminates with exit reason Reason, a 'DOWN' message is sent to Pid1:
{'DOWN', Ref, process, Pid2, Reason}
If Pid2 does not exist, the 'DOWN' message is sent immediately with Reason set to noproc.
Monitors are unidirectional. Repeated calls to erlang:monitor(process, Pid) will create several, independent monitors and each one will send a 'DOWN' message when Pid terminates.
A monitor can be removed by calling erlang:demonitor(Ref).
It is possible to create monitors for processes with registered names, also at other nodes.
Process Dictionary
Each process has its own process dictionary, accessed by calling the following BIFs:
| put(Key, Value) |
| get(Key) |
| get() |
| get_keys(Value) |
| erase(Key) |
| erase() |
11 Distributed Erlang 11.1 Distributed Erlang System
A distributed Erlang system consists of a number of Erlang runtime systems communicating with each other. Each such runtime system is called a node. Message passing between processes at different nodes, as well as links and monitors, are transparent when pids are used. Registered names, however, are local to each node. This means the node must be specified as well when sending messages etc. using registered names.
The distribution mechanism is implemented using TCP/IP sockets. How to implement an alternative carrier is described in ERTS User's Guide. 11.2 Nodes
A node is an executing Erlang runtime system which has been given a name, using the command line flag -name (long names) or -sname (short names).
The format of the node name is an atom name@host where name is the name given by the user and host is the full host name if long names are used, or the first part of the host name if short names are used. node() returns the name of the node. Example:
% erl -name dilbert (dilbert@uab.ericsson.se)1> node(). 'dilbert@uab.ericsson.se'
% erl -sname dilbert (dilbert@uab)1> node(). dilbert@uab
Note
A node with a long node name cannot communicate with a node with a short node name. 11.3 Node Connections
The nodes in a distributed Erlang system are loosely connected. The first time the name of another node is used, for example if spawn(Node,M,F,A) or net_adm:ping(Node) is called, a connection attempt to that node will be made.
Connections are by default transitive. If a node A connects to node B, and node B has a connection to node C, then node A will also try to connect to node C. This feature can be turned off by using the command line flag -connect_all false, see erl(1).
If a node goes down, all connections to that node are removed. Calling erlang:disconnect(Node) will force disconnection of a node.
The list of (visible) nodes currently connected to is returned by nodes(). 11.4 epmd
The Erlang Port Mapper Daemon epmd is automatically started at every host where an Erlang node is started. It is responsible for mapping the symbolic node names to machine addresses. See epmd(1). 11.5 Hidden Nodes
In a distributed Erlang system, it is sometimes useful to connect to a node without also connecting to all other nodes. An example could be some kind of O&M functionality used to inspect the status of a system without disturbing it. For this purpose, a hidden node may be used.
A hidden node is a node started with the command line flag -hidden. Connections between hidden nodes and other nodes are not transitive, they must be set up explicitly. Also, hidden nodes does not show up in the list of nodes returned by nodes(). Instead, nodes(hidden) or nodes(connected) must be used. This means, for example, that the hidden node will not be added to the set of nodes that global is keeping track of.
This feature was added in Erlang 5.0/OTP R7. 11.6 C Nodes
A C node is a C program written to act as a hidden node in a distributed Erlang system. The library Erl_Interface contains functions for this purpose. Refer to the documentation for Erl_Interface and Interoperability Tutorial for more information about C nodes. 11.7 Security
Authentication determines which nodes are allowed to communicate with each other. In a network of different Erlang nodes, it is built into the system at the lowest possible level. Each node has its own magic cookie, which is an Erlang atom.
When a nodes tries to connect to another node, the magic cookies are compared. If they do not match, the connected node rejects the connection.
At start-up, a node has a random atom assigned as its magic cookie and the cookie of other nodes is assumed to be nocookie. The first action of the Erlang network authentication server (auth) is then to read a file named $HOME/.erlang.cookie. If the file does not exist, it is created. The UNIX permissions mode of the file is set to octal 400 (read-only by user) and its contents are a random string. An atom Cookie is created from the contents of the file and the cookie of the local node is set to this using erlang:set_cookie(node(), Cookie). This also makes the local node assume that all other nodes have the same cookie Cookie.
Thus, groups of users with identical cookie files get Erlang nodes which can communicate freely and without interference from the magic cookie system. Users who want run nodes on separate file systems must make certain that their cookie files are identical on the different file systems.
For a node Node1 with magic cookie Cookie to be able to connect to, or accept a connection from, another node Node2 with a different cookie DiffCookie?, the function erlang:set_cookie(Node2, DiffCookie?) must first be called at Node1. Distributed systems with multiple user IDs can be handled in this way.
The default when a connection is established between two nodes, is to immediately connect all other visible nodes as well. This way, there is always a fully connected network. If there are nodes with different cookies, this method might be inappropriate and the command line flag -connect_all false must be set, see erl(1).
The magic cookie of the local node is retrieved by calling erlang:get_cookie(). 11.8 Distribution BIFs
Some useful BIFs for distributed programming, see erlang(3) for more information:
Distribution BIFs. erlang:disconnect_node(Node) Forces the disconnection of a node. erlang:get_cookie() Returns the magic cookie of the current node. is_alive() Returns trueif the runtime system is a node and can connect to other nodes, falseotherwise. monitor_node(Node, true|false) Monitor the status of Node. A message{nodedown, Node}is received if the connection to it is lost. node() Returns the name of the current node. Allowed in guards. node(Arg) Returns the node where Arg, a pid, reference, or port, is located. nodes() Returns a list of all visible nodes this node is connected to. nodes(Arg) Depending on Arg, this function can return a list not only of visible nodes, but also hidden nodes and previously known nodes, etc. set_cookie(Node, Cookie) Sets the magic cookie used when connecting to Node. If Nodeis the current node, Cookiewill be used when connecting to all new nodes. spawn[_link|_opt](Node, Fun) Creates a process at a remote node. spawn[_link|opt](Node, Module, FunctionName?, Args) Creates a process at a remote node. 11.9 Distribution Command Line Flags
Examples of command line flags used for distributed programming, see erl(1) for more information:
Distribution Command Line Flags. -connect_all false Only explicit connection set-ups will be used. -hidden Makes a node into a hidden node. -name Name Makes a runtime system into a node, using long node names. -setcookie Cookie Same as calling erlang:set_cookie(node(), Cookie). -sname Name Makes a runtime system into a node, using short node names. 11.10 Distribution Modules
Examples of modules useful for distributed programming:
In Kernel:
Kernel Modules Useful For Distribution. global A global name registration facility. global_group Grouping nodes to global name registration groups. net_adm Various Erlang net administration routines. net_kernel Erlang networking kernel.
In STDLIB:
STDLIB Modules Useful For Distribution.
code MODULE code MODULE SUMMARY Erlang Code Server DESCRIPTION
This module contains the interface to the Erlang code server, which deals with the loading of compiled code into a running Erlang runtime system.
The runtime system can be started in either embedded or interactive mode. Which one is decided by the command line flag -mode.
% erl -mode interactive
Default mode is interactive.
- In embedded mode, all code is loaded during system start-up according to the boot script. (Code can also be loaded later by explicitly ordering the code server to do so).
- In interactive mode, only some code is loaded during system startup-up, basically the modules needed by the runtime system itself. Other code is dynamically loaded when first referenced. When a call to a function in a certain module is made, and the module is not loaded, the code server searches for and tries to load the module.
To prevent accidently reloading modules affecting the Erlang runtime system itself, the kernel, stdlib and compiler directories are considered sticky. This means that the system issues a warning and rejects the request if a user tries to reload a module residing in any of them. The feature can be disabled by using the command line flag -nostick. Code Path
In interactive mode, the code server maintains a search path -- usually called the code path -- consisting of a list of directories, which it searches sequentially when trying to load a module.
Initially, the code path consists of the current working directory and all Erlang object code directories under the library directory $OTPROOT/lib, where $OTPROOT is the installation directory of Erlang/OTP, code:root_dir(). Directories can be named Name[-Vsn] and the code server, by default, chooses the directory with the highest version number among those which have the same Name. The -Vsn suffix is optional. If an ebin directory exists under Name[-Vsn], it is this directory which is added to the code path. Code Path Cache
The code server incorporates a code path cache. The cache functionality is disabled by default. To activate it, start the emulator with the command line flag -code_path_cache or call code:rehash(). When the cache is created (or updated), the code server searches for modules in the code path directories. This may take some time if the the code path is long. After the cache creation, the time for loading modules in a large system (one with a large directory structure) is significantly reduced compared to having the cache disabled. The code server is able to look up the location of a module from the cache in constant time instead of having to search through the code path directories.
Application resource files (.app files) are also stored in the code path cache. This feature is used by the application controller (see application(3)) to load applications efficiently in large systems.
Note that when the code path cache is created (or updated), any relative directory names in the code path are converted to absolute. Current and Old Code
The code of a module can exists in two variants in a system: current code and old code. When a module is loaded into the system for the first time, the code of the module becomes 'current' and the global export table is updated with references to all functions exported from the module.
If then a new instance of the module is loaded (perhaps because of the correction of an error), then the code of the previous instance becomes 'old', and all export entries referring to the previous instance are removed. After that the new instance is loaded as if it was loaded for the first time, as described above, and becomes 'current'.
Both old and current code for a module are valid, and may even be evaluated concurrently. The difference is that exported functions in old code are unavailable. Hence there is no way to make a global call to an exported function in old code, but old code may still be evaluated because of processes lingering in it.
If a third instance of the module is loaded, the code server will remove (purge) the old code and any processes lingering in it will be terminated. Then the third instance becomes 'current' and the previously current code becomes 'old'.
For more information about old and current code, and how to make a process switch from old to current code, refer to Erlang Reference Manual. Argument Types and Invalid Arguments
Generally, module and application names are atoms, while file and directory names are strings. For backward compatibility reasons, some functions accept both strings and atoms, but a future release will probably only allow the arguments that are documented.
From the R12B release, functions in this module will generally fail with an exception if they are passed an incorrect type (for instance, an integer or a tuple where an atom was expected). An error tuple will be returned if type of argument was correct, but there was some other error (for instance, a non-existing directory given to set_path/1. EXPORTS
set_path(Path) -> true | {error, What}
Types:
Path = [Dir]
Dir = string() What = bad_directory | bad_path
Sets the code path to the list of directories Path.
Returns true if successful, or {error, bad_directory} if any Dir is not the name of a directory, or {error, bad_path} if the argument is invalid.
get_path() -> Path
Types:
Path = [Dir]
Dir = string()
Returns the code path
add_path(Dir) -> true | {error, What} add_pathz(Dir) -> true | {error, What}
Types:
Dir = string() What = bad_directory
Adds Dir to the code path. The directory is added as the last directory in the new path. If Dir already exists in the path, it is not added.
Returns true if successful, or {error, bad_directory} if Dir is not the name of a directory.
add_patha(Dir) -> true | {error, What}
Types:
Dir = string() What = bad_directory
Adds Dir to the beginning of the code path. If Dir already exists, it is removed from the old position in the code path.
Returns true if successful, or {error, bad_directory} if Dir is not the name of a directory.
add_paths(Dirs) -> ok add_pathsz(Dirs) -> ok
Types:
Dirs = [Dir]
Dir = string()
Adds the directories in Dirs to the end of the code path. If a Dir already exists, it is not added. This function always returns ok, regardless of the validity of each individual Dir.
add_pathsa(Dirs) -> ok
Types:
Dirs = [Dir]
Dir = string()
Adds the directories in Dirs to the beginning of the code path. If a Dir already exists, it is removed from the old position in the code path. This function always returns ok, regardless of the validity of each individual Dir.
del_path(Name | Dir) -> true | false | {error, What}
Types:
Name = atom() Dir = string() What = bad_name
Deletes a directory from the code path. The argument can be an atom Name, in which case the directory with the name .../Name[-Vsn]/ebin is deleted from the code path. It is also possible to give the complete directory name Dir as argument.
Returns true if successful, or false if the directory is not found, or {error, bad_name} if the argument is invalid.
replace_path(Name, Dir) -> true | {error, What}
Types:
Name = atom() Dir = string() What = bad_name | bad_directory | {badarg, term()}
This function replaces an old occurrence of a directory named .../Name[-Vsn]/ebin, in the code path, with Dir. If Name does not exist, it adds the new directory Dir last in the code path. The new directory must also be named .../Name[-Vsn]/ebin. This function should be used if a new version of the directory (library) is added to a running system.
Returns true if successful, or {error, bad_name} if Name is not found, or {error, bad_directory} if Dir does not exist, or {error, {badarg, [Name, Dir]}} if Name or Dir is invalid.
load_file(Module) -> {module, Module} | {error, What}
Types:
Module = atom() What = nofile | sticky_directory | badarg | term()
Tries to load the Erlang module Module, using the code path. It looks for the object code file with an extension that corresponds to the Erlang machine used, for example Module.beam. The loading fails if the module name found in the object code differs from the name Module. load_binary/3 must be used to load object code with a module name that is different from the file name.
Returns {module, Module} if successful, or {error, nofile} if no object code is found, or {error, sticky_directory} if the object code resides in a sticky directory, or {error, badarg} if the argument is invalid. Also if the loading fails, an error tuple is returned. See erlang:load_module/2 for possible values of What.
load_abs(Filename) -> {module, Module} | {error, What}
Types:
Filename = string() Module = atom() What = nofile | sticky_directory | badarg | term()
Does the same as load_file(Module), but Filename is either an absolute file name, or a relative file name. The code path is not searched. It returns a value in the same way as load_file/1. Note that Filename should not contain the extension (for example ".beam"); load_abs/1 adds the correct extension itself.
ensure_loaded(Module) -> {module, Module} | {error, What}
Types:
Module = atom() What = nofile | sticky_directory | embedded | badarg | term()
Tries to to load a module in the same way as load_file/1. In embedded mode, however, it does not load a module which is not already loaded, but returns {error, embedded} instead.
load_binary(Module, Filename, Binary) -> {module, Module} | {error, What}
Types:
Module = atom() Filename = string() What = sticky_directory | badarg | term()
This function can be used to load object code on remote Erlang nodes. It can also be used to load object code where the file name and module name differ. This, however, is a very unusual situation and not recommended. The parameter Binary must contain object code for Module. Filename is only used by the code server to keep a record of from which file the object code for Module comes. Accordingly, Filename is not opened and read by the code server.
Returns {module, Module} if successful, or {error, sticky_directory} if the object code resides in a sticky directory, or {error, badarg} if any argument is invalid. Also if the loading fails, an error tuple is returned. See erlang:load_module/2 for possible values of What.
delete(Module) -> true | false
Types:
Module = atom()
Removes the current code for Module, that is, the current code for Module is made old. This means that processes can continue to execute the code in the module, but that no external function calls can be made to it.
Returns true if successful, or false if there is old code for Module which must be purged first, or if Module is not a (loaded) module.
purge(Module) -> true | false
Types:
Module = atom()
Purges the code for Module, that is, removes code marked as old. If some processes still linger in the old code, these processes are killed before the code is removed.
Returns true if successful and any process needed to be killed, otherwise false.
soft_purge(Module) -> true | false
Types:
Module = atom()
Purges the code for Module, that is, removes code marked as old, but only if no processes linger in it.
Returns false if the module could not be purged due to processes lingering in old code, otherwise true.
is_loaded(Module) -> {file, Loaded} | false
Types:
Module = atom() Loaded = Absname | preloaded | cover_compiled
Absname = string()
Checks if Module is loaded. If it is, {file, Loaded} is returned, otherwise false.
Normally, Loaded is the absolute file name Absname from which the code was obtained. If the module is preloaded (see script(4)), Loaded==preloaded. If the module is Cover compiled (see cover(3)), Loaded==cover_compiled.
all_loaded() -> [{Module, Loaded}]
Types:
Module = atom() Loaded = Absname | preloaded | cover_compiled
Absname = string()
Returns a list of tuples {Module, Loaded} for all loaded modules. Loaded is normally the absolute file name, as described for is_loaded/1.
which(Module) -> Which
Types:
Module = atom() Which = Filename | non_existing | preloaded | cover_compiled
Filename = string()
If the module is not loaded, this function searches the code path for the first file which contains object code for Module and returns the absolute file name. If the module is loaded, it returns the name of the file which contained the loaded object code. If the module is pre-loaded, preloaded is returned. If the module is Cover compiled, cover_compiled is returned. non_existing is returned if the module cannot be found.
get_object_code(Module) -> {Module, Binary, Filename} | error
Types:
Module = atom() Binary = binary() Filename = string()
Searches the code path for the object code of the module Module. It returns {Module, Binary, Filename} if successful, and error if not. Binary is a binary data object which contains the object code for the module. This can be useful if code is to be loaded on a remote node in a distributed system. For example, loading module Module on a node Node is done as follows:
... {_Module, Binary, Filename} = code:get_object_code(Module), rpc:call(Node, code, load_binary, [Module, Filename, Binary]), ...
root_dir() -> string()
Returns the root directory of Erlang/OTP, which is the directory where it is installed.
> code:root_dir(). "/usr/local/otp"
lib_dir() -> string()
Returns the library directory, $OTPROOT/lib, where $OTPROOT is the root directory of Erlang/OTP.
> code:lib_dir(). "/usr/local/otp/lib"
lib_dir(Name) -> string() | {error, bad_name}
Types:
Name = atom()
This function is mainly intended for finding out the path for the "library directory", the top directory, for an application Name located under $OTPROOT/lib.
If there is a directory called Name in the code path, optionally with a -Vsn suffix and/or an ebin subdirectory, the name of this directory is returned.
> code:lib_dir(mnesia). "/usr/local/otp/lib/mnesia-4.2.2"
Returns {error, bad_name} if Name is not the name of an application under $OTPROOT/lib. Fails with an exception if Name has the wrong type. Warning
For backward compatibiliy, Name is also allowed to be a string. That will probably change in a future release.
compiler_dir() -> string()
Returns the compiler library directory. Equivalent to code:lib_dir(compiler).
priv_dir(Name) -> string() | {error, bad_name}
Types:
Name = atom()
This function is mainly intended for finding out the path for the priv directory for an application Name located under $OTPROOT/lib.
If there is a directory called Name in the code path, optionally with a -Vsn suffix and/or an ebin subdirectory, the function returns the name of this directory with priv appended. It is not checked if this directory really exists.
> code:priv_dir(mnesia). "/usr/local/otp/lib/mnesia-4.2.2/priv"
Returns {error, bad_name} if Name is not the name of an application under $OTPROOT/lib. Fails with an exception if Name has the wrong type. Warning
For backward compatibiliy, Name is also allowed to be a string. That will probably change in a future release.
objfile_extension() -> ".beam"
Returns the object code file extension that corresponds to the Erlang machine used, namely ".beam".
stick_dir(Dir) -> ok | {error, What}
Types:
Dir = string() What = term()
This function marks Dir as sticky.
Returns ok if successful, and an error tuple otherwise.
unstick_dir(Dir) -> ok | {error, What}
Types:
Dir = string() What = term()
This function unsticks a directory which has been marked as sticky.
Returns ok if successful, and an error tuple otherwise.
rehash() -> ok
This function creates or rehashes the code path cache.
where_is_file(Filename) -> Absname | non_existing
Types:
Filename = Absname = string()
Searches the code path for Filename, a file of arbitrary type. If found, the full name is returned. non_existing is returned if the file cannot be found. The function can be useful, for example, to locate application resource files. If the code path cache is used, the code server will efficiently read the full name from the cache, provided that Filename is an object code file or an .app file.
clash() -> ok
Searches the entire code space for module names with identical names and writes a report to stdout. 13 Ports and Port Drivers
Examples of how to use ports and port drivers can be found in Interoperability Tutorial. The BIFs mentioned are as usual documented in erlang(3). 13.1 Ports
Ports provide the basic mechanism for communication with the external world, from Erlang's point of view. They provide a byte-oriented interface to an external program. When a port has been created, Erlang can communicate with it by sending and receiving lists of bytes, including binaries.
The Erlang process which creates a port is said to be the port owner, or the connected process of the port. All communication to and from the port should go via the port owner. If the port owner terminates, so will the port (and the external program, if it is written correctly).
The external program resides in another OS process. By default, it should read from standard input (file descriptor 0) and write to standard output (file descriptor 1). The external program should terminate when the port is closed. 13.2 Port Drivers
It is also possible to write a driver in C according to certain principles and dynamically link it to the Erlang runtime system. The linked-in driver looks like a port from the Erlang programmer's point of view and is called a port driver. Warning
An erroneous port driver will cause the entire Erlang runtime system to leak memory, hang or crash.
Port drivers are documented in erl_driver(4), driver_entry(1) and erl_ddll(3). 13.3 Port BIFs
To create a port:
Port Creation BIF. open_port(PortName?, PortSettings? Returns a port identifier Portas the result of opening a new Erlang port. Messages can be sent to and received from a port identifier, just like a pid. Port identifiers can also be linked to or registered under a name using link/1and register/2.
PortName? is usually a tuple {spawn,Command}, where the string Command is the name of the external program. The external program runs outside the Erlang workspace unless a port driver with the name Command is found. If found, that driver is started.
PortSettings? is a list of settings (options) for the port. The list typically contains at least a tuple {packet,N} which specifies that data sent between the port and the external program are preceded by an N-byte length indicator. Valid values for N are 1, 2 or 4. If binaries should be used instead of lists of bytes, the option binary must be included.
The port owner Pid can communicate with the port Port by sending and receiving messages. (In fact, any process can send the messages to the port, but the messages from the port always go to the port owner).
Below, Data must be an I/O list. An I/O list is a binary or a (possibly deep) list of binaries or integers in the range 0..255.
Messages Sent To a Port. {Pid,{command,Data}} Sends Datato the port. {Pid,close} Closes the port. Unless the port is already closed, the port replies with {Port,closed}when all buffers have been flushed and the port really closes. {Pid,{connect,NewPid?}} Sets the port owner of Portto NewPid?. Unless the port is already closed, the port replies with{Port,connected}to the old port owner. Note that the old port owner is still linked to the port, but the new port owner is not.
Messages Received From a Port. {Port,{data,Data}} Datais received from the external program. {Port,closed} Reply to Port ! {Pid,close}. {Port,connected} Reply to Port ! {Pid,{connect,NewPid?}} {'EXIT',Port,Reason} If the port has terminated for some reason.
Instead of sending and receiving messages, there are also a number of BIFs that can be used. These can be called by any process, not only the port owner.
Port BIFs. port_command(Port,Data) Sends Datato the port. port_close(Port) Closes the port. port_connect(Port,NewPid?) Sets the port owner of Portto NewPid?. The old port owner Pidstays linked to the port and have to call unlink(Port)if this is not desired. erlang:port_info(Port,Item) Returns information as specified by Item. erlang:ports() Returns a list of all ports on the current node.
There are some additional BIFs that only apply to port drivers: port_control/3 and erlang:port_call/3.
