Hidden Features of Erlang [closed]

一个人想着一个人 提交于 2019-11-27 16:38:45
legoscia

The magic commands in the shell. The full list is in the manual, but the ones I use most are:

  • f() - forget all variables
  • f(X) - forget X
  • v(42) - recall result from line 42
  • v(-1) - recall result from previous line
  • e(-1) - reexecute expression on previous line
  • rr(foo) - read record definitions from module foo
  • rr("*/*") - read record definitions from every module in every subdirectory
  • rp(expression) - print full expression with record formating
bjnortier

Inheritance! http://www.erlang.se/euc/07/papers/1700Carlsson.pdf

Parent

-module(parent).
-export([foo/0, bar/0]).

foo() ->
    io:format("parent:foo/0 ~n", []).

bar() ->
    io:format("parent:bar/0 ~n", []).

Child

-module(child).
-extends(parent).
-export([foo/0]).

foo() ->
    io:format("child:foo/0 ~n", []).

Console

23> parent:foo().
parent:foo/0 
ok
24> parent:bar().
parent:bar/0 
ok
25> child:foo().
child:foo/0 
ok
26> child:bar().
parent:bar/0 
ok
bjnortier

Parameterized Modules! From http://www.lshift.net/blog/2008/05/18/late-binding-with-erlang and http://www.erlang.se/euc/07/papers/1700Carlsson.pdf

-module(myclass, [Instvar1, Instvar2]).
-export([getInstvar1/0, getInstvar2/0]).
getInstvar1() -> Instvar1.
getInstvar2() -> Instvar2.

And

Eshell V5.6  (abort with ^G)
1> Handle = myclass:new(123, 234).
{myclass,123,234}
2> Handle:getInstvar1().
123
3> Handle:getInstvar2().
234

user_default.erl - you can build your own shell builtins by having a compiled user_default.beam in your path which can be pretty nifty

beam_lib:chunks can get source code from a beam that was compiled with debug on which can be really usefull

{ok,{_,[{abstract_code,{_,AC}}]}} = beam_lib:chunks(Beam,[abstract_code]).
  io:fwrite("~s~n", [erl_prettypr:format(erl_syntax:form_list(AC))]).

Ports, external or linked-in, accept something called io-lists for sending data to them. An io-list is a binary or a (possibly deep) list of binaries or integers in the range 0..255.

This means that rather than concatenating two lists before sending them to a port, one can just send them as two items in a list. So instead of

"foo" ++ "bar"

one do

["foo", "bar"]

In this example it is of course of miniscule difference. But the iolist in itself allows for convenient programming when creating output data. io_lib:format/2,3 itself returns an io list for example.

The function erlang:list_to_binary/1 accepts io lists, but now we have erlang:iolist_to_binary/1 which convey the intention better. There is also an erlang:iolist_size/1.

Best of all, since files and sockets are implemented as ports, you can send iolists to them. No need to flatten or append.

That match specifications can be built using ets:fun2ms(...) where the Erlang fun syntax is used and translated into a match specification with a parse transform.

1> ets:fun2ms(fun({Foo, _, Bar}) when Foo > 0 -> {Foo, Bar} end).
[{{'$1','_','$2'},[{'>','$1',0}],[{{'$1','$2'}}]}]

So no fun-value is ever built, the expression gets replaced with the match-spec at compile-time. The fun may only do things a match expression could do.

Also, ets:fun2ms is available for usage in the shell, so fun-expressions can be tested easily.

.erlang_hosts gives a nice way to share names across machines

Not necessarily "hidden", but I don't see this often. Anonymous functions can have multiple clauses, just like module functions, i.e.

-module(foo).
-compile(export_all).

foo(0) -> "zero";
foo(1) -> "one";
foo(_) -> "many".

anon() ->
    fun(0) ->
            "zero";
       (1) ->
            "one";
       (_) ->
            "many"
    end.


1> foo:foo(0).
"zero"
2> foo:foo(1).
"one"
3> foo:foo(2).
"many"

4> (foo:anon())(0).
"zero"
5> (foo:anon())(1).
"one"
6> (foo:anon())(2).
"many"

The gen___tcp and ssl sockets have a {packet, Type} socket option to aid in decoding a number of protocols. The function erlang:decode_packet/3 has a good description on what the various Type values can be and what they do.

Together with a {active, once} or {active, true} setting, each framed value will be delivered as a single message.

Examples: the packet http mode is used heavily for iserve and the packet fcgi mode for ifastcgi. I can imagine that many of the other http servers use packet http as well.

.erlang can preload libraries and run commands on a shells startup, you can also do specific commands for specific nodes by doing a case statement on node name.

If you want to execute more than one expression in a list comprehension, you can use a block. For example:

> [begin erlang:display(N), N*10 end || N <- lists:seq(1,3)].
1
2
3
[10,20,30]

It is possible to define your own iterator for QLC to use. For example, a result set from an SQL query could be made into a QLC table, and thus benefit from the features of QLC queries.

Besides mnesia tables, dets and ets have the table/1,2 functions to return such a "Query Handle" for them.

Not so hidden, but one of the most important aspects, when chosing Erlang as platform for development:

  • Possibility of enhanced tracing on live nodes (in-service) and being one of the best in debugging!

You can hide an Erlang node by starting it with:

erl -sname foo -hidden

You can still connect to the node, but it won't appear in the list returned by nodes/0.

Matching with the append operator:

"pajamas:" ++ Color = "pajamas:blue"

Color now has the value "blue". Be aware that this trick has it’s limitations - as far as I know it only works with a single variable and a single constant in the order given above.

Hot code loading. From wiki.

Code is loaded and managed as "module" units, the module is a compilation unit. The system can keep two versions of a module in memory at the same time, and processes can concurrently run code from each.

The versions are referred to the "new" and the "old" version. A process will not move into the new version until it makes an external call to its module.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!