[erlang-questions] How best to extract value from mnesia query
lloyd@REDACTED
lloyd@REDACTED
Thu Nov 16 00:31:58 CET 2017
Hi Jesper,
Thank you!
Lloyd
-----Original Message-----
From: "Jesper Louis Andersen" <jesper.louis.andersen@REDACTED>
Sent: Wednesday, November 15, 2017 4:44pm
To: lloyd@REDACTED
Cc: "Erlang" <erlang-questions@REDACTED>
Subject: Re: [erlang-questions] How best to extract value from mnesia query
I usually do something like:
Txn = fun() -> ... end,
case mnesia:transaction(Txn) of
{atomic, []} ->
not_found;
{atomic, [V]} ->
<One_Value_Case>
{atomic, L = [_|_]} ->
<Multi_Value_Case>
end.
Some times, if there are a bunch of cases, I tend to use a function such as
your confirm/1 function, passing the result on and writing down the case
split at the top level, but it depends a bit on wether I like that code
flow or not in that particular case. In general I prefer matching and
binding values over projection functions such as hd/1, because hd/1 doesn't
work on all lists, only the non-empty ones.
Another common trick is that if your Results are lists, then you can often
avoid using a not_found atom, but handle the [] case naturally. Consider
that
[] = lists:map(F, [])
which is true for a lot of functions working on lists. This suggests you
can avoid having multiple data flows in this case, and use [] as a
degenerate case which "skips" computations in a natural way. This can
sometimes turn a code flow which case-splits its control flow all the time
into a flow that just has one path. Flow with a single path tend to be far
easier to handle in the long run in my experience.
Also, if you really do expect there to be a value, then I use
{atomic, [Value]} = mnesia:transaction(Txn),
and crash the code if it is violated. Defensive code is often a mistake in
Erlang because we can just use the standard crash semantics to recover.
Many other languages doesn't fare so well here.
On Wed, Nov 15, 2017 at 9:04 PM <lloyd@REDACTED> wrote:
> Hello,
>
> The result of a mnesia read transaction looks like this:
>
> {atomic, Results} where result is either a populated list [value1, ...
> valueN] or, an empty list [].
>
> If the table is initialized as set, then the returned list will contain at
> most one value, e.g:
>
> [value].
>
> If I want to use of the value in a function or to populate another record,
> I need to extract the value from the list.
>
> I've tried various ways to do this, but they all seem clumsy:
>
> E.g.
>
> [MyValue]
>
> hd[vlaue]
>
> confirm([]) ->
> not_found;
> confirm([Value]) ->
> Value;
> confirm(Value) ->
> Value.
>
> Does there happen to be a preferred/conventional/best-practices way to do
> this?
>
> Many thanks,
>
> LRP
>
>
>
>
>
>
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://erlang.org/mailman/listinfo/erlang-questions
>
More information about the erlang-questions
mailing list