erlang: функция, вызываемая с реальным 'fun', должна быть преобразована с помощью parse_transform?
Я смотрю на книгу по программированию O'Reilly Erlang, и есть пример, который запускается в оболочке erlang, который выглядит так:
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]]
Тем не менее, когда я делаю что-то подобное в моем коде (не в оболочке):
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) будет перенос строки?)
Во всяком случае, я отказался от select в пользу ets:foldl, так как последний работает и - за исключением исключений в забаве - позволяет мне прекратить обход, когда найден первый элемент. Но мне все еще любопытно...
... ВАЗ? (Я немного читал на parse_transform, и я достаточно нов, чтобы понять, что мне не хватает соединения.)
1 ответ
badarg
исключение - это признак встроенной функции (или псевдофункции, как в данном случае), вызванной с неверным параметром. В этом случае ets:fun2ms/1
функция.
Чтение из официальной документации:
fun2ms (LiteralFun) -> MatchSpec
Псевдофункция, которая с помощью parse_transform транслирует LiteralFun, введенный в качестве параметра в вызове функции, в match_spec. Под "литералом" подразумевается, что веселье должно быть записано в тексте как параметр функции, его нельзя удерживать в переменной, которая, в свою очередь, передается функции).