Erlang匹配specs与元组比较

时间:2013-01-03 14:09:55

标签: erlang tuples matching

我希望在erlang datetime中使用标准格式{{Y,M,D},{H,Min,Sec}}中的MNESIA table值进行日志记录,并且能够通过与常量开始和结束时间元组进行比较来选择日志条目。 / p>

似乎matchspec保护编译器以某种方式将元组值与保护子表达式混淆。 <{1}}评估失败

ets:match_spec_compile(MatchSpec)

但是当我将MatchSpec = [ { {'_','$1','$2'} , [ {'==','$2',{1,2}} ] , ['$_'] } ] 与任何非元组值进行比较时会成功。

是否存在匹配防护无法比较元组值的限制?

1 个答案:

答案 0 :(得分:2)

我相信答案是在使用元组时使用双括号(参见http://www.erlang.org/doc/apps/erts/match_spec.html#id69408的变量和文字部分)。因此,要在matchspec表达式中使用元组,请使用大括号包围该元组,如,

{'==','$2',{{1,2}}}

所以,如果我正确理解你的例子,你就会有

22> M=[{{'_','$1','$2'},[{'==','$2',{{1,2}}}],['$_']}].
[{{'_','$1','$2'},[{'==','$2',{{1,2}}}],['$_']}]

23> ets:match_spec_run([{1,1,{1,2}}],ets:match_spec_compile(M)).
[{1,1,{1,2}}]

24> ets:match_spec_run([{1,1,{2,2}}],ets:match_spec_compile(M)).
[]

编辑 :(很抱歉编辑你的答案,但这是以可读形式发表评论的最简单方法) 是的,这是必须要做的。获取match-spec的一种更简单的方法是使用(伪)函数ets:fun2ms/1,它将 literal fun作为参数并返回match-spec。所以

10> ets:fun2ms(fun ({A,B,C}=X) when C == {1,2} -> X end).
[{{'$1','$2','$3'},[{'==','$3',{{1,2}}}],['$_']}]

shell识别ets:fun2ms/1。有关更多信息,请参阅ETS documentation。 Mnesia使用与ETS相同的匹配规范。