2

我正在看 O'Reilly Erlang Programming book 并且有一个在 erlang shell 中运行的示例,如下所示:

17> MS = ets:fun2ms(fun({Name,Country,Job}) when Job /= cook ->
                   [Country,Name] end).
[  ....an erlang match expression is returned....  ]
18> ets:select(countries, MS).
[[ireland,sean],[ireland,chris]]

但是,当我在代码中(而不是在 shell 中)执行类似操作时:

Fun = fun({Type,_,_,ObjectId,PlayerId}) when Type==player_atom, PlayerId==2 -> ObjectId end,
MatchFun = ets:fun2ms(Fun),
PlayerObjectId = ets:select(?roster_table, MatchFun),

我得到了FUBAR:

exit:{badarg,{ets,fun2ms,[function,called,with,real,'fun',should,be,transformed,with,parse_transform,'or',called,with,a,'fun',generated,in,the,shell]}}

(顺便说一句,我想知道为什么错误不是'用......调用的函数'可能是这样 io:format("~p", TheErrorMessage) 会换行?)

无论如何,我已经放弃了选择,转而使用 ets:foldl,因为后者有效,并且 - 通过有趣的异常 - 允许我在找到第一个项目时终止遍历。但是,我还是很好奇...

...世界卫生大会?(我在 parse_transform 上做了一些阅读,而且我对 erlang 足够陌生,以至于我错过了连接。)

4

1 回答 1

3

badarg异常是使用错误参数调用的内置函数(或本例中的伪函数)的症状。在这种情况下,ets:fun2ms/1函数。

阅读官方文档

fun2ms(LiteralFun) -> MatchSpec

通过 parse_transform 将函数调用中作为参数类型化的 LiteralFun 转换为 match_spec 的伪函数。使用“文字”意味着乐趣需要以文本形式写入函数的参数,它不能保存在变量中,而变量又传递给函数)。

于 2011-07-11T21:27:33.853 回答