2010-01-06 27 views
4

我正在嘗試從包含頭文件的表單編譯模塊。首先,如果我有源文件中的模塊,一切正常。使用包含的頭文件編譯表單

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}}]}],[]} 

我在做什麼錯?

回答

4

包含文件和宏由erlang預處理器epp處理。 compile:forms/1函數假定所有的預處理已經完成,因此它將處理{attribute,1,include,...}作爲未知屬性。與宏一樣。

今天沒有辦法在表單列表上運行預處理器。您將不得不明確包含該文件並進行宏處理。從表單和文件中提取一些輸入信息似乎也有點奇怪。

+0

感謝。我被這個文件誤導了。所以基本上我可以1)自己獲取標題,將它們解析爲表單,並用它們替換屬性,或者2)將我的表單打印到源文件,然後編譯。 – Zed 2010-01-07 07:29:31

+0

就是這樣。或者修復epp。 :-) – rvirding 2010-01-07 19:40:02

+0

僅供參考,有一個模塊用於對erl_scan返回的令牌進行預處理:https://github.com/evanmiller/aleppo – Emiller 2010-12-13 22:02:53

0

我們這樣做是爲了只爲記錄的項目,但它需要一個幾件事情:

  1. 你必須有一個模塊在運行時加載其中有你需要包括.hrl-文件(梁對於這個模塊也必須在路徑上可用)。
  2. 該模塊必須使用調試信息進行編譯(+debug_info到編譯器或[debug_info]作爲c/2的選項參數)。
  3. 您必須自己將.hrl記錄定義插入到表單中。

這裏是如何做到這一點:

首先創建一個模塊,其中包括.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}}]}]}]. 
+0

感謝分享。這是一個有趣的「解決方法」的問題:) – Zed 2010-01-12 10:32:59

+0

是的!這很好,因爲它總是提供最新版本的記錄,即使.hrl文件有變化(因爲my_hrl.erl得到重新編譯)。 – 2010-01-29 19:31:14

相關問題