fun2ms应该改造?

fun2ms should be transformed?

LYSE 书之后,在关于 Mnesia 的章节中,作者使用 fun2ms 提供了一个查询。由于某种原因,这给了我一个错误:

$ rebar3 ct
[0;32m===> Verifying dependencies...
[0m[0;32m===> Compiling mafiapp
[0m[0;32m===> Running Common Test suites...
[0m%%% mafiapp_SUITE ==> add_service: [0;32mOK[0m[0m

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
mnesia:wrap_trans failed on line 399
Reason: aborted
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

%%% mafiapp_SUITE ==> friend_by_name: [0;31mFAILED[0m[0m
%%% mafiapp_SUITE ==> [0;31m{failed,{aborted,{badarg,{ets,fun2ms,
                              [function,called,with,real,'fun',should,be,
                               transformed,with,parse_transform,'or',called,
                               with,a,'fun',generated,in,the,shell]}}}}[0m[0m

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
mnesia:wrap_trans failed on line 399
Reason: aborted
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

%%% mafiapp_SUITE ==> friend_with_services: [0;31mFAILED[0m[0m
%%% mafiapp_SUITE ==> [0;31m{failed,{aborted,{badarg,{ets,fun2ms,
                              [function,called,with,real,'fun',should,be,
                               transformed,with,parse_transform,'or',called,
                               with,a,'fun',generated,in,the,shell]}}}}[0m[0m
Failed 2 tests. Passed 1 tests.
Results written to "d:/Projects/vms/erlang/projects/erlang-patterns/src/examples/mafiapp/_build/test/logs/index.html".
[0;31m===> Failures occured running tests: 2
[0m

请参阅下面 mafiapp.erl 文件中的 find_services 函数:

-module(mafiapp).

%% API exports
-export([install/1, add_friend/4, add_service/4, friend_by_name/1]).

%% Records
-record(mafiapp_friends, {name,
                           contact=[],
                           info=[],
                           expertise}).
-record(mafiapp_services, {from,
                            to,
                            date,
                            description}).

%%====================================================================
%% API
%%====================================================================
add_friend(Name, Contact, Info, Expertise) ->
    F = fun() ->
        mnesia:write(#mafiapp_friends{name=Name, contact=Contact, info=Info, expertise=Expertise})
    end,
    mnesia:activity(transaction, F).

add_service(From, To, Date, Description) ->
    F = fun() ->
        case mnesia:read({mafiapp_friends, From}) =:= [] orelse
            mnesia:read({mafiapp_friends, To}) =:= [] of
            true -> {error, unknown_friend};
            false -> mnesia:write(#mafiapp_services{from=From, to=To, date=Date, description=Description})
        end
    end,
    mnesia:activity(transaction, F).

friend_by_name(Name) ->
    F = fun() ->
        case mnesia:read({mafiapp_friends, Name}) of
            [#mafiapp_friends{contact=C, info=I, expertise=E}] ->
                {Name,C,I,E,find_services(Name)};
            [] -> undefined
        end
    end,
    mnesia:activity(transaction, F).

install(Nodes) ->
    ok = mnesia:create_schema(Nodes),
    rpc:multicall(Nodes, application, start, [mnesia]),
    mnesia:create_table(mafiapp_friends,
        [{attributes, record_info(fields, mafiapp_friends)},
         {index, [#mafiapp_friends.expertise]},
         {disc_copies, Nodes}]),
    mnesia:create_table(mafiapp_services,
        [{attributes, record_info(fields, mafiapp_services)},
         {index, [#mafiapp_services.to]},
         {disc_copies, Nodes},
         {type, bag}]),
    rpc:multicall(Nodes, application, stop, [mnesia]).

%% Private functions
find_services(Name) -> 
    Match = ets:fun2ms(
            fun(#mafiapp_services{from=From, to=To, date=D, description=Desc})
                when From =:= Name ->
                    {to, To, D, Desc};
                (#mafiapp_services{from=From, to=To, date=D, description=Desc})
                 when To =:= Name ->
                    {from, From, D, Desc}
            end
    ),
    mnesia:select(mafiapp_services, Match).

请帮忙。

您必须将 ms_transform 解析转换插入到您的模块中才能使 ets:fun2ms 工作。

-include_lib("stdlib/include/ms_transform.hrl").

有关详细信息,请参阅 ets:fun2ms/1 文档。