Erlang和运行时记录限制

时间:2009-01-15 15:33:49

标签: erlang runtime

我正在开发一个Erlang系统并且存在重复出现的问题,即记录是编译时预处理器宏(几乎),并且它们无法在运行时进行操作...... 基本上,我正在使用属性模式,其中属性在运行时添加到前端(AS3)上的对象。理想情况下,我会在Erlang方面用一个列表来反映这一点,因为它是一个基本的数据类型,但是在QCL [查询ETS表]中使用记录是不可能的,因为使用它们我必须具体说出哪个记录​​属性我想查询...我在larges表中至少有15列,所以在一个巨大的switch语句中列出它们(案例X)只是简单的丑陋。

有没有人有任何想法如何优雅地解决这个问题?也许一些内置函数用于创建具有适当签名的元组以用于模式匹配(用于QLC)?

感谢

3 个答案:

答案 0 :(得分:4)

听起来您希望能够执行get_record_field(Field, SomeRecord)之类的操作,其中Field在运行时由用户界面代码确定。

你是对的,你不能在标准的erlang中做这些记录,并且record_info函数在编译时被扩展和消除。

我使用或查看过几种解决方案。我的解决方案如下:(该示例提供对#dns_rec的{​​{1}}和#dns_rr记录的运行时访问权限

inet_dns.hrl

这里有一个编译的版本:rec_test.erl


您还可以将此动态字段查找扩展为动态生成匹配规范,以便与%% Retrieves the value stored in the record Rec in field Field. info(Field, Rec) -> Fields = fields(Rec), info(Field, Fields, tl(tuple_to_list(Rec))). info(_Field, _Fields, []) -> erlang:error(bad_record); info(_Field, [], _Rec) -> erlang:error(bad_field); info(Field, [Field | _], [Val | _]) -> Val; info(Field, [_Other | Fields], [_Val | Values]) -> info(Field, Fields, Values). %% The fields function provides the list of field positions %% for all the kinds of record you want to be able to query %% at runtime. You'll need to modify this to use your own records. fields(#dns_rec{}) -> fields(dns_rec); fields(dns_rec) -> record_info(fields, dns_rec); fields(#dns_rr{}) -> fields(dns_rr); fields(dns_rr) -> record_info(fields, dns_rr). %% Turns a record into a proplist suitable for use with the proplists module. to_proplist(R) -> Keys = fields(R), Values = tl(tuple_to_list(R)), lists:zip(Keys,Values). ets:select/2一起使用,如下所示:

mnesia:select/2

Ulf Wiger还写了一个parse_transform,Exprecs,或多或少会自动为你做这件事。我从未尝试过,但Ulf的代码通常非常好。


答案 1 :(得分:1)

我通过使用解析转换工具来解决这个问题(在开发中)来读取.hrl文件并生成帮助函数。

我在tutorial上写了一个Trap Exit

我们一直使用它来生成匹配规格。美丽的是,你不需要知道任何关于开发时记录的当前状态

然而,一旦你在生产中,事情会发生变化!如果你的记录是表格的基础(而不是表格中字段的定义)那么更改基础记录就更难了(说得温和一点!)。

答案 2 :(得分:0)

我不确定我是否完全理解您的问题,但在大多数情况下我已从记录移至proplists。它们更灵活,速度更慢。使用(d)ets我通常使用几个记录字段进行粗略选择,然后检查剩余记录上的支持者以进行详细选择。