Erlang: qlc:info 抛出错误,而 qlc:eval 没有 - 为什么?

发布于 2024-10-31 15:43:35 字数 1272 浏览 0 评论 0 原文

有效

root@test # 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().

无效

root@test # 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().

我不明白为什么。在一个更复杂的查询中发现了此错误,由于此错误,我无法解释和分析该错误。

Works

root@test # 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().

Does not work

root@test # 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().

I can't understand why. Discovered this error on a much more complex query that I'm not able to explain and profile because of this error.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

我家小可爱 2024-11-07 15:43:35

尽管该帖子很旧,但我想了解这种行为。我的理解有什么不对的地方请指正。

考虑代码中的以下更改

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)

当调试qlc的代码时发现,对于match_spec_run相关的查询处理qlc:info使用抽象格式函数erl_parse:parse_exprs/1 获取解析树。但这种情况下的问题是 Erlang 引用没有解析树!为了简单理解 NewRef = #Ref<0.0.0.134>. 和 pid NewPid = <0.34.0>. 给出语法错误,它们只能是值绑定到变量,编译器无法解释/解析它们。因此在这种情况下会导致错误。

Even though the post is very old, I wanted to understand the behavior. Please correct me wherever there is something wrong in my understanding.

Consider the following change in the code

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'}}]}]))"

The change in the output is that match_spec_run is used in the second case(qlc handles are different). This means there is a change how the qlc info needs to get the data from the qlc handle.

The below code gives error

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)

When debugging the code of qlc found that, for match_spec_run related query handle the qlc:info uses abstract format function erl_parse:parse_exprs/1 to get the parse tree. But the problem in this case is that the Erlang reference has no parse tree!! For simple understanding NewRef = #Ref<0.0.0.134>. and also pid NewPid = <0.34.0>. gives syntax error, they can only be values bound to a variable and compiler cannot interpret/parse them. Thus in this case it results in the error.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文