[erlang-questions] Suggestion for the Mnesia manual

Philip Robinson <>
Mon May 5 04:36:16 CEST 2008


Hi Bill.

I am a big fan of putting the expected return value on every line that
is otherwise used for side-effects.  Unification will then ensure that
the code aborts on the first line in error; the later lines don't even
get a chance to run.

i.e.:
init() ->
    {atomic, ok} = mnesia:create_table(t1...),
    {atomic, ok} = mnesia:create_table(t2...),
    {atomic, ok} = mnesia:create_table(t2...).

Even using anonymous vars helps, e.g.:
    {ok, _} = some_side_effect_fun(),
ensures that the return value wasn't {error, 'some message'} before continuing.

Cheers,
Philip

On Mon, May 5, 2008 at 10:38 AM, Bill Robertson
<> wrote:
> In section 3.3.1 (Initializing a Schema and Starting Mnesia) of the
>  Mnesia manual,
>  there is a function similar to this...
>
>  -module(foo).
>  -export([init/0, init2/0, init3/0]).
>
>  -record(foo, {a, b}).
>  -record(bar, {a, b}).
>  -record(baz, {a, b}).
>
>  init() ->
>     mnesia:create_table(t1, [{attributes,record_info(fields, foo)},
>                              {disk_only_copies, [node()]} ]),
>     mnesia:create_table(t2, [{attributes,record_info(fields, bar)},
>                              {disk_only_copies, [node()]} ]),
>     mnesia:create_table(t3, [{attributes,record_info(fields, baz)},
>                              {disk_only_copies, [node()]} ]).
>
>  43> foo:init().
>  {aborted,{badarg,t3,disk_only_copies}}
>
>  The example in the manual is o.k. because it does not misspell "disc"
>  like my code did.  I'm new to the language, so I didn't realize what
>  the real problem was.  I only saw the error for the third table, and
>  I spent the entire afternoon trying to figure out why the third statement
>  failed when the first two didn't.  Of course, that wasn't the problem
>  at all.  I just failed to understand that I was only seeing the return
>  value of the last expression in the function and that they had all
>  failed.
>
>  I would like to suggest that the example in the Mnesia manual be
>  rewritten to put the table information into a list and then call
>  mnesia:create_table() in a list comprehension and return the result
>  of that.  This version returns the result of all calls, and might
>  save somebody new to the language some time if they base their
>  code off of the manual, because they would see all of their errors.
>
>  init2() ->
>     Tables = [{t1, [{attributes,record_info(fields, foo)},
>                     {disk_only_copies, [node()]} ]},
>               {t2, [{attributes,record_info(fields, bar)},
>                     {disk_only_copies, [node()]} ]},
>               {t3, [{attributes,record_info(fields, baz)},
>                     {disk_only_copies, [node()]} ]}],
>     [create_table(Table) || Table <- Tables].
>
>  create_table(TableInfo) ->
>     {Table, Args} = TableInfo,
>     mnesia:create_table(Table, Args).
>
>  44> foo:init2().
>  [{aborted,{badarg,t1,disk_only_copies}},
>   {aborted,{badarg,t2,disk_only_copies}},
>   {aborted,{badarg,t3,disk_only_copies}}]
>
>  init3() ->
>     Tables = [{t1, [{attributes,record_info(fields, foo)},
>                     {disc_only_copies, [node()]} ]},
>               {t2, [{attributes,record_info(fields, bar)},
>                     {disc_only_copies, [node()]} ]},
>               {t3, [{attributes,record_info(fields, baz)},
>                     {disc_only_copies, [node()]} ]}],
>     [create_table(Table) || Table <- Tables].
>
>  45> foo:init3().
>  [{atomic,ok},{atomic,ok},{atomic,ok}]
>
>  Thanks



More information about the erlang-questions mailing list