Forms 编译包含头文件的表单
我试图从表单中编译一个模块,其中包含头文件。首先,如果我有一个源文件中的模块,一切正常 user.hrlForms 编译包含头文件的表单,forms,erlang,compilation,Forms,Erlang,Compilation,我试图从表单中编译一个模块,其中包含头文件。首先,如果我有一个源文件中的模块,一切正常 user.hrl -record(user, {name :: string()}). -module(zed). -export([f/1]). -include("user.hrl"). f(User) -> User#user.name. 1> compile:file(zed, [return]). {ok,zed,[]} 2> rr("user.hrl"). [use
-record(user, {name :: string()}).
-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"
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}}]}],[]}
zed.erl
-record(user, {name :: string()}).
-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"
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}}]}],[]}
壳牌公司
-record(user, {name :: string()}).
-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"
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}}]}],[]}
如果我试图从表单编译相同的模块,我会得到一个未定义的记录错误。玩{i,Dir}
和其他选项没有帮助
壳牌公司
-record(user, {name :: string()}).
-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"
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}}]}],[]}
我做错了什么?包括文件和宏,由erlang预处理器epp处理。compile:forms/1函数假定所有预处理都已经完成,因此它将把
{attribute,1,include,…}
作为未知属性进行处理。宏也是如此
现在无法在表单列表上运行预处理器。您必须显式地包含该文件并执行宏处理。从表单和文件中获取一些输入似乎也有点奇怪。我们这样做只是为了记录,但它需要一些东西:
+debug\u info
到编译器,或使用[debug\u info]
作为c/2
的选项参数)-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].
谢谢这方面的文件误导了我。因此,基本上我可以1)自己获取标题,将其解析为表单,并用它们替换属性,或者2)将表单漂亮地打印到源文件中,然后进行编译。或修复epp:-)仅供参考,有一个模块用于对erl_扫描返回的代币进行预处理:感谢分享。这是一个有趣的问题解决方法:)是的!这很好,因为它总是提供最新版本的记录,即使.hrl文件发生了更改(因为my_hrl.erl get被重新编译)。