HOWTO Erlang Custom Behaviors (шаблонный шаблон).
-1. Написать общий модуль. Здесь определен алгоритм, но некоторые шаги (функции обратного вызова в номенклатуре Эрланга) оставлены для будущего конкретного определения.
%% generic.erl
-module(generic).
-export( [sayHello/1] ).
-callback say(Num :: term()) -> term(). %% future definition
%% generic algorithm: needs the reference to the provider module
sayHello(ProviderModule) ->
io:fwrite( "Hello 1: ~p\n", [ ProviderModule:say(1) ]) ,
io:fwrite( "Hello 2: ~p\n", [ ProviderModule:say(2) ]) .
-2. Скомпилируйте generic.erl
erlc generic.erl
- (3.) Попробуйте написать модуль провайдера (обратного вызова)
%% callbacks1.erl (fails to implement say/1 callback)
-module( callbacks1 ).
-behaviour( generic ).
- (4.) Скомпилируйте callbacks1.erl: используйте -pa. , чтобы сказать, где находится generic.beam. (Поэтому выдается ожидаемое предупреждение о say / 1).
erlc -pa . callbacks1.erl
callbacks1.erl:2: Warning: undefined callback function say/1 (behaviour 'generic')
(Примечание: если -pa не задано, вы получите следующее: "callbacks1.erl: 2: Предупреждение: универсальное поведение не определено")
-3. Напишите правильный модуль провайдера (обратного вызова).
%% callbacks2.erl
-module( callbacks2 ).
-behaviour( generic ).
-export( [say/1] ).
say(1) -> "good morning";
say(2) -> "bon jour";
say(_) -> "hi".
-4. Скомпилируйте
erlc -pa . callbacks2.erl
(Хорошо, сейчас).
* * -5 тысячу двадцать восемь. Напишите main.erl для сбора универсального модуля с модулем обратного вызова.
%% main.erl
-module( main ).
-export( [main/0] ).
main() ->
%% call the generic algorithm telling it what callback module to use
generic:sayHello( callbacks2 )
. % ()
-6. Скомпилируйте и запустите main
erlc main.erl
erl -noshell -s main main -s init stop
Получаем:
Hello 1: "good morning"
Hello 2: "bon jour"