erlang: function called with real 'fun' should be transformed with parse_transform?

匿名 (未验证) 提交于 2019-12-03 09:05:37

问题:

I'm looking at the O'Reilly Erlang Programming book and there's an example that is run in the erlang shell that looks like this:

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]]

However, when I do something similar in my code (not in the shell):

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

I get 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]}}

(As an aside, I wonder why the error isn't 'function called with....' Probably so io:format("~p", TheErrorMessage) will line wrap?)

Anyway, I have abandoned select in favor of ets:foldl, since the latter works and - through exceptions in the fun - allows me to terminate the traversal when the first item is found. But, I'm still curious...

...wha? (I did some reading on parse_transform, and I'm new enough to erlang that I'm missing the connection.)

回答1:

The badarg exception is symptom of a built-in function (or a pseudo function, as in this case) called with a wrong parameter. In this case, the ets:fun2ms/1 function.

Reading from the official documentation:

fun2ms(LiteralFun) -> MatchSpec

Pseudo function that by means of a parse_transform translates LiteralFun typed as parameter in the function call to a match_spec. With "literal" is meant that the fun needs to textually be written as the parameter of the function, it cannot be held in a variable which in turn is passed to the function).



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!