2011-07-11 85 views
1

我期待在O'Reilly的Erlang編程的書,還有的是在Erlang的外殼,看起來像這樣運行的例子:erlang:用真正的'fun'調用的函數應該用parse_transform?

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:格式( 「〜 「)

無論如何,我放棄了選擇,以支持ets:foldl,因爲後者可以工作,並且 - 通過fun中的例外 - 允許我在第一個項目結束時終止遍歷找到。但是,我仍然好奇...

... wha? (我做了一些關於parse_transform的閱讀,並且我已經足夠新到erlang,我錯過了連接。)

回答

3

badarg異常是內置函數(或僞函數,如本例中的症狀)用錯誤的參數調用。在這種情況下,ets:fun2ms/1函數。

the official documentation讀:

fun2ms(LiteralFun) - > MatchSpec

功能,通過一個parse_transform的手段轉化 LiteralFun類型爲在函數調用到match_spec參數。 「文字」意味着樂趣需要在文本上寫爲 函數的參數,它不能被保存在一個變量中,而該變量又被傳遞給函數)。

+1

請注意,您仍然可以在您正在編寫的函數內部定義的樂趣中使用'select/2',或者自行編寫匹配規範。 –