2011-04-13 160 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>.給出了語法錯誤,它們只能是綁定到變量的值,編譯器不能解釋/解析它們。因此在這種情況下會導致錯誤。

相關問題