Скрытые возможности Erlang

В духе:

  • Скрытые возможности C#
  • Скрытые возможности Java
  • Скрытые возможности ASP.NET
  • Скрытые возможности Python
  • Скрытые возможности HTML
  • и другие вопросы о скрытых функциях

О каких скрытых особенностях Erlang должен знать каждый разработчик Erlang?

Одна скрытая функция в ответе, пожалуйста.

17 ответов

Решение

Магические команды в оболочке. Полный список приведен в руководстве, но больше всего я использую:

  • f () - забыть все переменные
  • f(X) - забыть X
  • v (42) - вызвать результат из строки 42
  • v (-1) - вызвать результат из предыдущей строки
  • e(-1) - повторно выполнить выражение в предыдущей строке
  • rr (foo) - читать определения записей из модуля foo
  • rr ("* / *") - читать определения записей из каждого модуля в каждом подкаталоге
  • rp (выражение) - вывести полное выражение с форматированием записи

Наследование! http://www.erlang.se/euc/07/papers/1700Carlsson.pdf

родитель

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

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

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

ребенок

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

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

Приставка

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

Параметризованные модули! От http://www.lshift.net/blog/2008/05/18/late-binding-with-erlang и http://www.erlang.se/euc/07/papers/1700Carlsson.pdf

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

А также

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 - вы можете создавать свои собственные встроенные оболочки, имея скомпилированный user_default.beam на своем пути, который может быть довольно изящным

beam_lib: чанки могут получить исходный код от луча, который был скомпилирован с отладкой, что может быть действительно полезным

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

Порты, внешние или связанные, принимают так называемые списки io-списков для отправки им данных. Io-list - это двоичный или (возможно, глубокий) список двоичных файлов или целых чисел в диапазоне 0..255.

Это означает, что вместо объединения двух списков перед отправкой их в порт можно просто отправить их как два элемента в списке. Так что вместо

"foo" ++ "bar"

один делать

["foo", "bar"]

В этом примере это, конечно, незначительная разница. Но сам по себе iolist обеспечивает удобное программирование при создании выходных данных. Например, io_lib:format/2,3 возвращает список io.

Функция erlang:list_to_binary/1 принимает списки io, но теперь у нас есть erlang:iolist_to_binary/1, который лучше передает намерение. Существует также erlang:iolist_size/1.

Лучше всего, поскольку файлы и сокеты реализованы в виде портов, вы можете отправлять в них iolist. Нет необходимости выравнивать или добавлять.

Спецификации соответствия могут быть построены с использованием ets:fun2ms(...), где используется синтаксис Erlang fun и преобразован в спецификацию соответствия с преобразованием синтаксического анализа.

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

Так что никакой забавной ценности никогда не создается, выражение заменяется на match-spec во время компиляции. Веселье может делать только то, что может делать выражение соответствия.

Кроме того, ets: fun2ms доступен для использования в оболочке, поэтому выражения-выражения можно легко протестировать.

.erlang_hosts дает хороший способ обмениваться именами между компьютерами

Не обязательно "скрытый", но я не вижу этого часто. Анонимные функции могут иметь несколько предложений, как и функции модуля, т.е.

-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"

В сокетах gen___tcp и ssl есть опция сокета {package, Type}, помогающая декодировать несколько протоколов. Функция erlang:decode_packet/3 имеет хорошее описание того, что могут быть различные значения типа и что они делают.

Вместе с настройкой {active, once} или {active, true} каждое значение в рамке будет доставлено как одно сообщение.

Примеры: режим http пакета интенсивно используется для iserve и режим fcgi пакета для ifastcgi. Я могу представить, что многие другие http-серверы также используют пакетный http.

.erlang может предварительно загружать библиотеки и запускать команды при запуске оболочки, вы также можете выполнять определенные команды для определенных узлов, выполняя инструкцию case для имени узла.

Если вы хотите выполнить более одного выражения в понимании списка, вы можете использовать блок. Например:

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

Не такой скрытый, но один из самых важных аспектов при выборе Erlang в качестве платформы для разработки:

  • Возможность улучшенной трассировки на живых узлах (в рабочем состоянии) и быть одним из лучших в отладке!

Можно определить свой собственный итератор для использования QLC. Например, набор результатов из запроса SQL может быть преобразован в таблицу QLC и, таким образом, использовать преимущества запросов QLC.

Помимо таблиц mnesia, dets и ets имеют функции table/1,2, которые возвращают им такой "дескриптор запроса".

Вы можете скрыть узел Erlang, запустив его с:

erl -sname foo -hidden

Вы все еще можете подключиться к узлу, но он не появится в списке, возвращаемом nodes/0,

Соответствие с оператором добавления:

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

Цвет теперь имеет значение "синий". Имейте в виду, что у этого трюка есть свои ограничения - насколько я знаю, он работает только с одной переменной и одной константой в указанном выше порядке.

Горячая загрузка кода. Из вики.

Код загружается и управляется как "модульные" модули, модуль является модулем компиляции. Система может хранить две версии модуля в памяти одновременно, и процессы могут одновременно запускать код из каждой.

Версии относятся к "новой" и "старой" версии. Процесс не переместится в новую версию, пока не выполнит внешний вызов своего модуля.

Другие вопросы по тегам