erlang mnesia-非法记录信息
我正在尝试使用一个函数来确保我所需要的表已经创建,如果不创建它的话。以下是示例:erlang mnesia-非法记录信息,erlang,record,mnesia,Erlang,Record,Mnesia,我正在尝试使用一个函数来确保我所需要的表已经创建,如果不创建它的话。以下是示例: ensure_table_exists(Table, MnesiaTables, Nodes) -> case lists:member(Table, MnesiaTables) of true -> throw({error, db_might_have_already_been_created}); false -> mnesia:create_
ensure_table_exists(Table, MnesiaTables, Nodes) ->
case lists:member(Table, MnesiaTables) of
true ->
throw({error, db_might_have_already_been_created});
false ->
mnesia:create_table(Table, [{disc_copies, Nodes},
{attributes, record_info(fields, Table)}]),
ok
end.
问题是编译时出现错误:非法记录信息
。
可能需要这样做:record\u info在编译时解析,或者record info的第二个参数实际上应该是一个可以从源代码中检索的记录?您可能需要查看一下 阅读描述: 该模块是一个解析转换 允许您导出记录。这个 transform为添加访问器函数 实例化、检查和测试 修改记录,而无需 引入编译时依赖关系 在模块之间 尽管如此,我还是觉得你的功能有点保守。下页解释了为什么在Erlang中进行防御编程是一个坏习惯: 是的,所有与记录相关的事情,包括
record\u info/2
都在编译时解决。这意味着记录和字段名必须在编译时已知。这就是编译器错误的原因
我不认为你的函数真的太过保守,因为你所做的只是发出一个更具体的错误信号。如果您返回{error,…}
,那将是另一回事
最后一点是,如果要引发异常,则不应使用throw/1
,而应使用erlang:error/1
throw
用于非本地返回(使用catch
捕获),而erlang:error
用于引发异常。在许多情况下,结果可能相同,但实际错误值可能会产生误导(nocatch
)。你越清楚地表明你的意图越好,在这种情况下,这是一个错误的信号
是的,我知道,
catch
也会捕获错误/退出。这是故意的。在一个完美的世界中,可能catch
只应捕获抛出的内容,而try
只应捕获错误/退出。不幸的是,record\u info实际上不是一个函数,即使它看起来像一个函数
您可以通过测试以下各项来验证这一点。创建一个文件:
-module(something).
-record(a, {}).
启动Erlang shell:
> rr(something).
[a]
> record_info(fields, a).
[]
> A = a.
> record_info(fields, A).
* 2: illegal record info
因此,我的建议是对记录信息部分使用宏或专用函数
回答你原来的问题。使用类似于:
tables() ->
[?TABLE_MACRO(tablename),
?TABLE_MACRO(tablename2),
...].
-define(TABLE_MACRO(Table), fun() ->
mnesia:create_table(Table, [{disc_copies, Nodes},
{attributes, record_info(fields, Table)}])
end).
其中,TABLE_宏类似于:
tables() ->
[?TABLE_MACRO(tablename),
?TABLE_MACRO(tablename2),
...].
-define(TABLE_MACRO(Table), fun() ->
mnesia:create_table(Table, [{disc_copies, Nodes},
{attributes, record_info(fields, Table)}])
end).
然后使用下面的函数
[case CreateTable of
{aborted, {already_exists, _}} -> ok;
{atomic, ok} -> ok
end || CreateTable <- tables()].
[case CreateTable of
{中止,{已经存在,{}}->确定;
{原子,ok}->ok
end | | CreateTable我知道在Erlang中进行防御性编程的坏习惯,但我不明白这与我的函数有什么关系?我只是想确保我没有创建模式。