Erlang 和运行时记录限制
我正在开发一个 Erlang 系统,并且反复出现问题,因为记录是编译时预处理器宏(几乎),并且它们无法在运行时进行操作...... 基本上,我正在使用属性模式,其中属性在运行时添加到前端(AS3)上的对象。 理想情况下,我会在 Erlang 端用一个列表来反映这一点,因为它是一种基本数据类型,但是使用 QCL 中的记录[查询 ETS 表]是不可能的,因为要使用它们,我必须具体说明我要使用哪个记录属性想要查询...我在大型表中至少有 15 列,因此将它们全部列在一个巨大的 switch 语句(case X of)中简直是丑陋的。
有谁有任何想法如何优雅地解决这个问题? 也许有一些内置函数用于创建具有适当签名的元组以用于模式匹配(对于 QLC)?
谢谢
I'm developing an Erlang system and having reoccurring problems with the fact that records are compile-time pre-processor macros (almost), and that they cant be manipulated at runtime...
basically, I'm working with a property pattern, where properties are added at run-time to objects on the front-end (AS3). Ideally, I would reflect this with a list on the Erlang side, since its a fundamental data type, but then using records in QCL [to query ETS tables] would not be possible since to use them I have to specifically say which record property I want to query over... I have at least 15 columns in the larges table, so listing them all in one huge switch statement (case X of) is just plain ugly.
does anyone have any ideas how to elegantly solve this? maybe some built-in functions for creating tuples with appropriate signatures for use in pattern matching (for QLC)?
thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
听起来您希望能够执行类似
get_record_field(Field, SomeRecord)
的操作,其中Field
在运行时由用户界面代码确定。你是对的,你不能在标准 erlang 中执行此操作,因为记录和 record_info 函数在编译时扩展和消除。
我使用过或研究过几种解决方案。 我的解决方案如下:(该示例提供对
inet_dns.hrl
中的#dns_rec
和#dns_rr
记录的运行时访问)此版本可以在此处进行编译: rec_test.erl
您还可以将此动态字段查找扩展到动态生成匹配规范与
ets:select/2
或mnesia:select/2
一起使用,如下所示:Ulf Wiger 还编写了一个 parse_transform,Exprecs,或多或少会自动为您完成此操作。 我从未尝试过,但 Ulf 的代码通常非常好。
It sounds like you want to be able to do something like
get_record_field(Field, SomeRecord)
whereField
is determined at runtime by user interface code say.You're right in that you can't do this in standard erlang as records and the
record_info
function are expanded and eliminated at compile time.There are a couple of solutions that I've used or looked at. My solution is as follows: (the example gives runtime access to the
#dns_rec
and#dns_rr
records frominet_dns.hrl
)A version of this that compiles is available here: rec_test.erl
You can also extend this dynamic field lookup to dynamic generation of matchspecs for use with
ets:select/2
ormnesia:select/2
as shown below:Ulf Wiger has also written a parse_transform, Exprecs, that more or less does this for you automagically. I've never tried it, but Ulf's code is usually very good.
我通过使用解析转换工具读取 .hrl 文件并生成辅助函数来解决这个问题(正在开发中)。
我在 教程 上编写了一个陷阱退出。
我们一直使用它来生成比赛规范。 美妙之处在于您在开发时不需要了解有关记录当前状态的任何信息。
然而,一旦投入生产,事情就会发生变化! 如果您的记录是表的基础(而不是表中字段的定义),则更改基础记录会更加困难(温和地说!)。
I solve this problem (in development) by use the parse transform tools to read the .hrl files and generate helper functions.
I wrote a tutorial on it at Trap Exit.
We use it all the time to generate match specs. The beauty is that you don't need to know anything about the current state of the record at development time.
However once you are in production things change! If your record is the basis of a table (as opposed to the definition of a field in a table) then changing an underlying record is more difficult (to put it mildly!).
我不确定我是否完全理解您的问题,但我已从记录移至 proplists 在大多数情况下。 它们更加灵活,但速度也慢得多。 使用 (d)ets 我通常使用一些记录字段进行粗略选择,然后检查其余记录上的 proplist 进行详细选择。
I'm not sure I fully understand your Problem but I have moved from records to proplists in most cases. They are much more flexible and much slower. Using (d)ets I usually use a few record fields for coarse selection and then check the proplists on the remaining records for detailed selection.