Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/efcasado/behaviours2
Erlang behaviours on steroids.
https://github.com/efcasado/behaviours2
Last synced: 5 days ago
JSON representation
Erlang behaviours on steroids.
- Host: GitHub
- URL: https://github.com/efcasado/behaviours2
- Owner: efcasado
- License: mit
- Created: 2015-02-06T13:24:05.000Z (almost 10 years ago)
- Default Branch: master
- Last Pushed: 2022-12-03T08:54:00.000Z (almost 2 years ago)
- Last Synced: 2024-08-01T13:24:44.381Z (3 months ago)
- Language: Erlang
- Size: 24.4 KB
- Stars: 8
- Watchers: 3
- Forks: 3
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- awesome-ccamel - efcasado/behaviours2 - Erlang behaviours on steroids. (Erlang)
README
behaviours2
===========Erlang behaviours on steroids.
`behaviours2` allows developers to provide sound defaults for a behaviour's
callbacks. `behaviours2`'s parse transform will automatically inject a
callback's default implementation unless the user overwrites it by providing
a custom implementation.### Examples
##### Simple behaviour
```erlang
-module(my_awesome_behaviour).%% To avoid problems when using `warnings_as_errors`
-export([export_all]).-type t1() :: any().
-type t2() :: any().-callback f1() -> t1().
-callback f2() -> t2().
-callback f3() -> t2().f1() ->
'default_f1'.f2() ->
'default_f2'.
f3() ->
f2().
``````erlang
-module(my_awesome_module).-compile({parse_transform, bhvs2_pt}).
-behaviour(my_awesome_behaviour).
f2() ->
'custom_f2'.```
```erlang
my_awesome_module:f1().
% => default_f1my_awesome_module:f2().
% => custom_f2my_awesome_module:f3().
% => custom_f2.
```Note that `f1` and `f3` were automatically injected into `my_awesome_module`. Note as well that no
explicit exports for the injected callback functions nor the provided one were required.##### gen_server (echo server)
The code snippet below illustrates how much effort it would take to
write an echo server.```erlang
-module(echo_server).-compile({parse_transform, bhv2_pt}).
-behaviour(gen_server).
-export([handle_call/3]).
handle_call(Msg, From, State) ->
Reply = Msg,
{reply, Msg, State}.```
Below is its plain Erlang/OTP counterpart.
```erlang
-module(echo_server).-behaviour(gen_server).
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2,
code_change/3]).-record(state, {}).
-type state() :: #state{}.
-spec init(Args :: []) ->
{ok, state()} |
{ok, state(), timeout()} |
ignore |
{stop, Reason :: term()}.
init([]) ->
{ok, #state{}}.-spec handle_call(Request :: term(),
From :: {pid(), Tag :: term()},
State :: state()) ->
{reply, Reply :: term(), state()} |
{reply, Reply :: term(), state(), timeout()} |
{noreply, state()} |
{noreply, state(), timeout()} |
{stop, Reason :: term(), Reply :: term(), state()} |
{stop, Reason :: term(), state()}.
handle_call(Msg, _From, State) ->
Reply = Msg,
{reply, Reply, State}.-spec handle_cast(Msg :: term(),
State :: state()) ->
{noreply, state()} |
{noreply, state(), timeout()} |
{stop, Reason :: term(), state()}.
handle_cast(Msg, State) ->
{noreply, State}.-spec handle_info(Info :: term(),
State :: state()) ->
{noreply, state()} |
{noreply, state(), timeout()} |
{stop, Reason :: term(), state()}.
handle_info(Info, State) ->
{noreply, State}.-spec terminate(Reason :: term(),
State :: state()) -> any().
terminate(_Reason, _State) ->
ok.-spec code_change(OldVsn :: term() | {down, Vsn :: term()},
State :: state(),
Extra :: term()) ->
{ok, NewState :: state()}.
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
```Quite a significant difference. Don't you think?