2011-04-13 161 views
1

作品Erlang:qlc:info会抛出一个错误,而qlc:eval不会 - 为什么?

[email protected] # erl 
Erlang R14B02 (erts-5.8.3) [source] [64-bit] [smp:4:4] [rq:4] [async-threads:0] [kernel-poll:false] 

Eshell V5.8.3 (abort with ^G) 
1> Tmp = ets:new(test, [bag]), Ref = make_ref(), 
1> qlc:eval(qlc:q([Ref1 || Ref1 <- ets:table(Tmp), Ref =:= Ref1])). 
[] 
2> qlc:info(qlc:q([Ref1 || Ref1 <- ets:table(Tmp), Ref =:= Ref1])). 
"ets:table(16400,\n   [{traverse,\n   {select,\n    [{'$1',\n    [{'=:=',{const,#Ref<0.0.0.29>},'$1'}],\n    ['$1']}]}}])" 
3> halt(). 

不工作

[email protected] # erl 
Erlang R14B02 (erts-5.8.3) [source] [64-bit] [smp:4:4] [rq:4] [async-threads:0] [kernel-poll:false] 

Eshell V5.8.3 (abort with ^G) 
1> Tmp = ets:new(test, [bag]), Ref = make_ref(), 
1> qlc:eval(qlc:q([Ref1 || {Ref1} <- ets:table(Tmp), Ref =:= Ref1])). 
[] 
2> qlc:info(qlc:q([Ref1 || {Ref1} <- ets:table(Tmp), Ref =:= Ref1])). 
** exception error: no match of right hand side value {error,{1,erl_parse,["syntax error before: ",["Ref"]]}} 
    in function qlc:abstract/3 
    in call from qlc:abstract/3 
    in call from qlc:abstract/4 
    in call from qlc:info/2 
3> halt(). 

我不明白为什么。在一个更复杂的查询中发现了这个错误,因为这个错误,我无法解释和配置文件。

+1

有趣的是,如果你调用它两次,qlc:info/1成功。 – 2011-04-15 10:13:11

+0

你可以发布PoC吗?我不确定我了解你的意思。 – trytrytry 2011-04-23 11:53:44

+0

这是一个古老的问题,我很惊讶它还没有回答或关闭。我的问题是,为什么你将表中的引用存储为{Ref}而不是Ref? – pedromanoel 2012-06-13 14:14:21

回答

1

尽管帖子很老,但我想了解这种行为。请在我理解的地方出现问题的地方纠正我。

考虑以下变化中的代码

1> Tmp = ets:new(test, [bag]), Ref = my_own_ref, 
qlc:info(qlc:q([Ref1 || Ref1 <- ets:table(Tmp), (Ref1 =:= Ref) ])). 
"ets:table(16400,\n   [{traverse,\n   {select,[{'$1',[{'=:=','$1 
',{const,my_own_ref}}],['$1']}]}}])" 
2> qlc:info(qlc:q([{Val1} || {Ref1,Val1} <- ets:table(Tmp), (Ref1 =:= Ref) ])). 
"ets:match_spec_run(ets:lookup(16400, my_own_ref),\n     ets:match 
_spec_compile([{{'$1','$2'},[],[{{'$2'}}]}]))" 

在输出中的变化是,match_spec_run在第二情况下,使用(QLC手柄是不同的)。这意味着qlc信息需要从qlc句柄中获取数据有所变化。

下面的代码提供了错误

1> Tmp = ets:new(test, [bag]), Ref = make_ref(). 
#Ref<0.0.0.25> 
2> qlc:info(qlc:q([{Val1} || {Ref1,Val1} <- ets:table(Tmp), (Ref1 =:= Ref) ])). 
** exception error: no match of right hand side value 
        {error,{1,erl_parse,["syntax error before: ",["Ref"]]}} 
    in function qlc:abstract/3 (d:/workspace/test/src/qlc.erl, line 1177) 
    in call from qlc:abstract/3 (d:/workspace/test/src/qlc.erl, line 1196) 
    in call from qlc:abstract/4 (d:/workspace/test/src/qlc.erl, line 1142) 
    in call from qlc:info/2 (d:/workspace/test/src/qlc.erl, line 445) 

当调试通活的发现,对于match_spec_run相关查询办理通活代码:信息使用abstract format功能erl_parse:parse_exprs/1得到解析树。但在这种情况下的问题是Erlang引用没有解析树!为了简单理解,NewRef = #Ref<0.0.0.134>.和pid NewPid = <0.34.0>.给出了语法错误,它们只能是绑定到变量的值,编译器不能解释/解析它们。因此在这种情况下会导致错误。

相关问题