[erlang-questions] extending function clauses
Zvi
exta7@REDACTED
Sat Dec 20 02:42:49 CET 2008
Hi Ittay,
Function caluses in Erlang are just syntactic shugar for case, i.e.
f(Pattern1) -> E1;
f(Pattern2) -> E2;
...
f(PatternN) -> EN.
is equivalent to:
f(X) ->
case X of
f(Pattern1) -> E1;
f(Pattern2) -> E2;
...
f(PatternN) -> EN
end.
The function clauses must be defined in consequtive order in the same source
file.
here the textbook shapes example I wrote, to show how to program in Erlang
in OOP style:
========= gen_shape.erl =======
-module(gen_shape).
-export([behaviour_info/1]).
behaviour_info(callbacks) ->
[{area, 1}];
behaviour_info(_Other) ->
undefined.
========= geometry.erl =======
-module(geometry).
-behaviour(gen_shape).
-export([area/1]).
area({Module, Shape}) -> Module:area(Shape).
========= rectangle.erl =======
-module(rectangle).
-behaviour(gen_shape).
-export([new/2, area/1]).
new(Width,Height) when is_number(Width),
is_number(Height)
-> {?MODULE, {Width,Height}}.
area({Width, Height}) -> Width*Height.
========= square.erl =======
-module(square).
-behaviour(gen_shape).
-export([new/1, area/1]).
new(Size) when is_number(Size)
-> {?MODULE, Size}.
area(Size) when is_number(Size)
-> Size*Size.
========= circle.erl =======
-module(circle).
-behaviour(gen_shape).
-export([new/1, area/1]).
new(Radius) when is_number(Radius)
-> {?MODULE, Radius}.
area(Radius) when is_number(Radius)
-> math:pi()*Radius*Radius.
======= END ============
Example of usage:
19> Shape1 = rectangle:new(5,7).
{rectangle,{5,7}}
20> geometry:area(Shape1).
35
21> Shape2 = circle:new(10).
{circle,10}
22> geometry:area(Shape2).
314.1592653589793
23>
23> Shape3 = square:new(5).
{square,5}
24> geometry:area(Shape3).
25
25>
25> Shape4 = {pentagon,7}.
{pentagon,7}
26> geometry:area(Shape4).
** exception error: undefined function pentagon:area/1
Two easy modifications for this example:
1. It's possible to change this code to use both generic and specific area/1
function (change representation of each shape to be tuple {ModuleName,
ShapeData} and geometry:area/1 to:
area({Module, Shape}) -> Module:area({Module, Shape}).
2. Let's say, we want to derive square from rectange, so in rectange.erl:
new(Size) when is_number(Size)
-> new:rectangle(Size, Size).
%% still need to define area/1 b/c it's in behaviour
area(_) -> erlang:error({should,never,be,called}).
Hope this helps,
Zvi
--
View this message in context: http://www.nabble.com/extending-function-clauses-tp21091060p21100978.html
Sent from the Erlang Questions mailing list archive at Nabble.com.
More information about the erlang-questions
mailing list