#best practice #erlang #patterns #undocumented #syntactic sugar
epoch: 1259593980
Surprisingly, there exist a number of Erlang features rather undocumented and obviously not part of the official picture of the language. One such feature is module inheritance. It is possible to extend a module by another and inherit or overwrite functions. This sounds like OOP and in fact it looks like class inheritance. The following code shows a simple example.
-module(alpha).
-export([f1/0, f2/0, f3/0]).
f1() ->
alpha_f1.
f2() ->
alpha_f2.
f3() ->
alpha_f3.
-module(beta).
-extends(alpha).
% f2 not exported
-export([f1/0, f3/0]).
f1() ->
beta_f1.
f2() ->
beta_f2.
f3() ->
?BASE_MODULE:f3().
And this is a corresponding eshell session:
Eshell V5.7.4 (abort with ^G)
1> alpha:f1().
alpha_f1
2> beta:f1().
beta_f1
3> alpha:f2().
alpha_f2
4> beta:f2().
alpha_f2
5> alpha:f3().
alpha_f3
6> beta:f3().
alpha_f3
Now one may ask why such an amazing and by a good amount of Java people eagerly awaited feature is hidden. Well, probably because it could become a source of bad habit.
In object oriented programing it is considered good style to prefer composition over inheritance. So why should Erlang support extension when it is already build into the language to enforce strong functional decomposition? Why mess around with bugs caused by nebulous call stacks? Function f() is called, but it produces not the expected output. Why! Why? Simply because you forgot to export it in the extending module and it is called at the base module. Without extension you would have a suggestion by the compiler.
There may be very rare situations when module extension makes sense, for example when you find no other way as to rewrite a heavy module like gen_server to meet your needs. Most of the time it is simply bad practice and should be avoided. Don’t push your bug statistics by using undocumented sugar.
Powered by Tumblr; designed by Adam Lloyd and Ingo Schramm.