extending standard behaviours

Chris Pressey cpressey@REDACTED
Wed Apr 17 20:31:39 CEST 2002


On Tue, 16 Apr 2002 20:31:29 -0400
Vance Shipley <vances@REDACTED> wrote:

> 
> OK, I see how to do this now.  My new behaviour module will
> look like a user to the gen_fsm behaviour and so it exports
> the call backs that gen_fsm expects.  It will look like a
> behaviour to it's users so we export the same but possibly
> extended interface as gen_fsm to our users.  
> 
> I put this together and it seems to work brilliantly.  This
> gives me exactly what I wanted which is to be able to write
> generic handlers in one place and handle the specifics in
> the individual state hanlder modules.  For instance when 
> we terminate the fxs_fsm module's terminate/3 function will
> do it's own clean up (hang up a call in a signaling specific
> way) and then call the cha_fsm terminate function to do the
> common clean up tasks (write to a log).  Messages received
> by fxs_fsm which are not understood by it are forwarded on
> to chan_fsm which handles them in a generic way.
> 
> Thanks Chris!
> 
> 	-Vance

Actually, I was having problems with my e-mail yesterday, and I thought
that short message I sent might not have gone through.  Not being very
familiar with gen_fsm, I started putting together a more coherent and
complete example from scratch, and I ran into some problems with that idea
that worked so nicely in my own head  :)

In this example (attached), gen_cat.erl is a behaviour for a generic cat -
it exports a function meow/1, and insists that whatever module implements
it, exports a function meow_sound/0.  (It's not a great example, but it's
simple.)  puff.erl behaves to gen_cat.

gen_loud_cat.erl is a specialization of gen_cat which ensures that the
sound the cat makes is loud (printed in uppercase).  rusty.erl behaves to
gen_loud_cat.  gen_loud_cat behaves to gen_cat, and it 'intercepts' the
meow_sound function, calling httpd_util:to_upper/1 on the sound, before
passing it through to gen_cat.

The problem is that gen_loud_cat must cache it's callback module in an ets
table - because I couldn't see any other way for it to 'remember' what
module is implementing it.  That's not very elegant at all.  I guess
object-oriented languages use a list of superclasses - I know Perl does
something like that - but if Erlang behaviours are written with only a
singleton callback module in mind - it might be difficult to extend them. 
It might be easier, if they were written with a list of callback modules
in mind.

Or perhaps I simply missed something.  The other odd thing that I didn't
initially expect (thinking about this in somewhat too-OO terms) is that
whether, for example, puff.erl behaves to gen_cat or gen_loud_cat is, on
one level, irrelevant, since they both expose the same interface.  The
only difference is in how it's implemented- the specific behaviour.  You
can change the single line -behaviour(gen_cat) to -behaviour(gen_loud_cat)
in puff.erl, and this changes puff's behaviour.  But this is a good thing!
This is the sort of near-interchangeability we're looking for, I think.

Perhaps I missed a shortcut where a step could be skipped, but I'm not
sure what it is.  Anyway, I'm glad this hasn't turned out to be just an
exercise in navel-gazing... :)

Chris
-------------- next part --------------
A non-text attachment was scrubbed...
Name: gen_cat.erl
Type: application/octet-stream
Size: 362 bytes
Desc: not available
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20020417/6ae5db4d/attachment.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: puff.erl
Type: application/octet-stream
Size: 87 bytes
Desc: not available
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20020417/6ae5db4d/attachment-0001.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: gen_loud_cat.erl
Type: application/octet-stream
Size: 490 bytes
Desc: not available
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20020417/6ae5db4d/attachment-0002.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: rusty.erl
Type: application/octet-stream
Size: 133 bytes
Desc: not available
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20020417/6ae5db4d/attachment-0003.obj>


More information about the erlang-questions mailing list