拾遗笔记

record_info.org

record_info(fields,yourrecordname), record_info(size,yourrecordname),

这两个宏不像宏,函数不像函数的东西,可以在编译期进行展开,但是我如果想写一个
record到json 格式的转换函数的话,是没法实现的,因为它只在编译期有限,在运行
其一个 record 实际就是一个tuple,其中是取不到record 的field的名字的。
所以参照网上的资料写了下面一个工具,
作用是根据某个erlang头文件,提取出其中的record ,然后为其生成一个module
提供get_key get_value get_index ,fields_info等函数 ,可以得到record的相应信

https://github.com/jixiuf/helloerlang/blob/master/record_field/src/record_util.erl
比如有这样一个头文件myhead.hrl

-record(user,{id,name,age}).
-record(classes,{name,id,nums}).

我修改record_util.hrl中头部的几个宏,记其生成关于myhead.hrl的一个工具模块myhead_util.erl

-define(HEAD_FILE_PATH,"../include/myhead.hrl").%relative to ebin/
%% save ?MODULENAME.erl in this dir
-define(DEST_DIR,"../src"). %relative to ebin/
-define(MODULENAME,"myhead_util").
-define(INCLUDE_CMD_IN_DEST_MODULE,"-include(\"myhead.hrl\").").

自动生成的模块如下

%% This module automatically generated - do not edit

%%% This module provides utilities for getting info about records
%% suppose there is a record in myhead.erl

%% -record(user,[id,name,age]).
%% U=#user{id=100,name=joseph,age=11}.

%% get_index(user,id)==1
%% get_index(U,id)==1

%% get_value(U,id)==100
%% get_value(U,1)==100

%% get_key(U,1)==key
%% get_key(user,1)==key

%% fields_info(user)==[id,name,age]
%% fields_info(U)==[id,name,age]

%% length(user)==3
%% length(U)==3

-module(myhead_util).

-include("myhead.hrl").
-export([get_index/2,get_key/2,get_value/2,length/1,fields_info/1]).

%% get the filed index (1 based ) of a record
get_index(user,id)-> #user.id-1 ;
get_index(Record,id) when is_record(Record,user)-> #user.id-1 ;
get_index(user,name)-> #user.name-1 ;
get_index(Record,name) when is_record(Record,user)-> #user.name-1 ;
get_index(user,age)-> #user.age-1 ;
get_index(Record,age) when is_record(Record,user)-> #user.age-1 ;
get_index(user,F) -> exit({error,"Record: user has no field called "++atom_to_list(F)});
get_index(classes,name)-> #classes.name-1 ;
get_index(Record,name) when is_record(Record,classes)-> #classes.name-1 ;
get_index(classes,id)-> #classes.id-1 ;
get_index(Record,id) when is_record(Record,classes)-> #classes.id-1 ;
get_index(classes,nums)-> #classes.nums-1 ;
get_index(Record,nums) when is_record(Record,classes)-> #classes.nums-1 ;
get_index(classes,F) -> exit({error,"Record: classes has no field called "++atom_to_list(F)});
get_index(Record,_Field) -> exit({error,"Invalid Record Name: "++Record}).

%% get field value of a record by index(1 based) or field name
get_value(Record,id) when  is_record(Record,user)->Record#user.id;
get_value(Record,1) when  is_record(Record,user)->Record#user.id;
get_value(Record,name) when  is_record(Record,user)->Record#user.name;
get_value(Record,2) when  is_record(Record,user)->Record#user.name;
get_value(Record,age) when  is_record(Record,user)->Record#user.age;
get_value(Record,3) when  is_record(Record,user)->Record#user.age;
get_value(user,Index) -> exit({error,"Record: user has no field index "++integer_to_list(Index)});
get_value(Record,name) when  is_record(Record,classes)->Record#classes.name;
get_value(Record,1) when  is_record(Record,classes)->Record#classes.name;
get_value(Record,id) when  is_record(Record,classes)->Record#classes.id;
get_value(Record,2) when  is_record(Record,classes)->Record#classes.id;
get_value(Record,nums) when  is_record(Record,classes)->Record#classes.nums;
get_value(Record,3) when  is_record(Record,classes)->Record#classes.nums;
get_value(classes,Index) -> exit({error,"Record: classes has no field index "++integer_to_list(Index)});
get_value(Record,_KeyIndex) -> exit({error,"Invalid Record Name: "++Record}).

%% get field name by index
get_key(user,1)-> id;
get_key(Record,1) when is_record(Record,user) ->id;
get_key(user,2)-> name;
get_key(Record,2) when is_record(Record,user) ->name;
get_key(user,3)-> age;
get_key(Record,3) when is_record(Record,user) ->age;
get_key(user,Index) -> exit({error,"Record: user has no field index "++integer_to_list(Index)});
get_key(classes,1)-> name;
get_key(Record,1) when is_record(Record,classes) ->name;
get_key(classes,2)-> id;
get_key(Record,2) when is_record(Record,classes) ->id;
get_key(classes,3)-> nums;
get_key(Record,3) when is_record(Record,classes) ->nums;
get_key(classes,Index) -> exit({error,"Record: classes has no field index "++integer_to_list(Index)});
get_key(Record,_Index) -> exit({error,"Invalid  Record Name or Index out of bound : "++lists:flatten(io_lib:format("~p",[Record]))}).

%% get all field name of a record
fields_info(classes) -> [name,id,nums];
fields_info(Record ) when is_record(Record,classes)->[name,id,nums];
fields_info(user) -> [id,name,age];
fields_info(Record ) when is_record(Record,user)->[id,name,age];
fields_info(Other) -> exit({error,"Invalid Record Name: "++Other}).

%% get count of fields of a record
length(classes) -> 3;
length(Record ) when is_record(Record,classes)->3;
length(user) -> 3;
length(Record ) when is_record(Record,user)->3;
length(Other) -> exit({error,"Invalid Record Name: "++Other}).

Comments

comments powered by Disqus