我正在尝试从表单编译一个模块,其中包含了头文件。首先,如果我将模块放在源文件中,那么一切都很好。
user.hrl
-record(user, {name :: string()}).zed.erl
-module(zed).
-export([f/1]).
-include("user.hrl").
f(User) ->
User#user.name.外壳
1> compile:file(zed, [return]).
{ok,zed,[]}
2> rr("user.hrl").
[user]
3> zed:f(#user{name = "Zed"}).
"Zed"如果我试图从窗体编译相同的模块,就会得到一个未定义的记录错误。使用{i, Dir}和其他选项没有帮助。
外壳
1> Forms = [{attribute,1,module,zed},
1> {attribute,1,export,[{f,1}]},
1> {attribute,1,include,"user.hrl"},
1> {function,1,f,1,
1> [{clause,1,
1> [{var,1,'User'}], [],
1> [{record_field,1,
1> {var,1,'User'},
1> user,
1> {atom,1,name}}]}]}].
....
2> compile:forms(Forms, [return]).
{error,[{".",[{1,erl_lint,{undefined_record,user}}]}],[]}我做错了什么?
发布于 2010-01-06 21:48:36
包含文件和宏由erlang预处理器epp处理。{attribute,1,include,...}:forms/1函数假定所有预处理都已经完成,因此它将作为一个未知属性来处理该。宏也是如此。
现在没有办法在表单列表上运行预处理器。您必须显式地包含文件并执行宏处理。从表单中获取一些输入,从文件中获取一些输入,似乎也有点奇怪。
发布于 2010-01-12 10:03:14
我们这样做只是为了记录一个项目,但它需要几件事:
c/2).
以下是如何做到这一点:
首先创建一个模块,其中包含..hrl文件:
-module(my_hrl).
-include("my_hrl.hrl").
-export([records/0]).
records() ->
{_Module, _Beam, FilePath} = code:get_object_code(?MODULE),
{ok, {_, [{abstract_code, {_, AC}}]}} =
beam_lib:chunks(FilePath, [abstract_code]),
[R || {attribute, _, record, _} = R <- AC].这将为您提供一个模块,它的include/0函数将为该模块中的所有记录提供一个抽象代码列表(来自..hrl嵌入其中的文件)。
当然,这种方法也可以用于记录属性以外的其他属性(甚至是..hrl文件中的函数)。
一旦您有了记录属性的列表,您只需将它们附加到表单中:
Forms = [{attribute,1,module,zed},
{attribute,1,export,[{f,1}]}]
++ my_hrl:records() ++
[{function,1,f,1,
[{clause,1,
[{var,1,'User'}], [],
[{record_field,1,
{var,1,'User'},
user,
{atom,1,name}}]}]}].https://stackoverflow.com/questions/2013119
复制相似问题