[erlang-questions] Modules and function "encapsulation"

Ulf Wiger <>
Mon Sep 6 08:38:46 CEST 2010


On 09/06/2010 12:02 AM, Richard O'Keefe wrote:
> 
> As it stands, -extends(bar) says
> "I don't know and I don't care what bar exports.
>  I trust bar TOTALLY.
>  Whatever bar exports, today, tomorrow, or until the Sun
>  goes out, I export that too."
> That really does not seem to be in the spirit of Erlang to me.


OTOH, it is pretty much exactly what one wants when e.g.
providing a mnesia callback module - it is required to support
all operations in the callback API, but in many cases, you
really only care about modifying a few of the functions.

When I last made a custom mnesia callback, it was to update
vector clocks for the unsplit behaviour.

The mnesia callback required looked something like this:

-module(my_mnesia_cb).
...
-include(“table_defs.hrl”).
-export_records([....]).

write(Tid, Ts, Tab, Rec, LockKind) ->
   Rec1 = try Old = ‘#get-’(Rec, [vclock]),
              ‘#set-’(
                  Rec,
                  [{vclock, unsplit_vclock:increment(node(), Old)}])
          catch
             error:badarg ->
               Rec
          end,
   mnesia:write(Tid,Ts,Tab,Rec1,LockKind).

Of course, in this case, the "..." could use the -extends()
option, or it could explicitly import the needed callback
functions. We can easily enough find out which ones they are:

$ grep 'Mod:' $otp/lib/mnesia/src/mnesia.erl
  Mod:lock(Tid, Ts, LockItem, LockKind);
  Mod:write(Tid, Ts, Tab, Val, LockKind);
  Mod:delete(Tid, Ts, Tab, Key, LockKind);
  Mod:delete_object(Tid, Ts, Tab, Val, LockKind);
  Mod:read(Tid, Ts, Tab, Key, LockKind);
  Mod:first(Tid, Ts, Tab);
  Mod:last(Tid, Ts, Tab);
  Mod:next(Tid,Ts,Tab,Key);
  Mod:prev(Tid,Ts,Tab,Key);
  Mod:foldl(Tid, Ts, Fun, Acc, Tab, LockKind);
  Mod:foldr(Tid, Ts, Fun, Acc, Tab, LockKind);
  Mod:match_object(Tid, Ts, Tab, Pat, LockKind);
  Mod:select(Tid, Ts, Tab, Pat, LockKind);
  Mod:select(Tid, Ts, Tab, Pat, NObjects, LockKind);
  Mod:select_cont(Tid,Ts,Cont);
  Mod:all_keys(Tid, Ts, Tab, read);
  Mod:index_match_object(Tid, Ts, Tab, Pat, Attr, LockKind);
  Mod:index_read(Tid, Ts, Tab, Key, Attr, read);
  Mod:table_info(Tid, Ts, Tab, Item);
  Mod:clear_table(Tid, Ts, Tab, '_');

...but in this case, I really only care about the write function,
now and forever, unless mnesia would add another function that
I'd have to wrap.

Whether this is such a representative case that it warrants a
language extension, I really can't say, and personally, I've yet
to use -extends() myself.

Of course, without -extends(), or at least your suggested change
for -import(), writing such a mnesia callback is tedious and
error-prone, since the majority of the line count goes into
re-mapping functions that we really do not care about.

BR,
Ulf W


More information about the erlang-questions mailing list