2011-04-13 7 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이 두 번 호출되면 성공한다는 것입니다. –

+0

PoC를 게시 할 수 있습니까? 나는 당신이 무슨 뜻인지 이해하지 못했습니다. – trytrytry

+0

이것은 오래된 질문이며, 여전히 답을 찾지 못했거나 닫힌 것이 놀랍습니다. 제 질문은 왜 그냥 참조 대신 {참조} 테이블에 참조를 저장합니까? – pedromanoel

답변

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 핸들에서 데이터를 가져 오는 데 필요한 변경이 있음을 의미합니다. match_spec_run 관련 쿼리에 대한 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) 

을 제공합니다 : 정보는 파스 트리를 얻을 수 abstract format 기능 erl_parse:parse_exprs/1를 사용합니다. 그러나이 경우의 문제는 Erlang 참조가 파스 트리가 없다는 것입니다! 간단한 이해를 위해 NewRef = #Ref<0.0.0.134>. 및 pid NewPid = <0.34.0>.은 구문 오류를 나타내며 변수에 바인딩 된 값일 수 있으며 컴파일러는 해석/해석 할 수 없습니다. 따라서이 경우 오류가 발생합니다.

관련 문제