因为erlang陈年关键字query导致的一个bug

在使用wrangler进行erlang代码重构时遇到一个问题,wrangler在解析包含query关键字的文件时出错。分析发现,query作为mysql库中的函数名在实际运行中稳定,但wrangler无法正确处理。简化问题后确认query是导致重构失败的原因。进一步的核对和修复工作正在进行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

某天使用erlang的重构工具wrangler进行重构的时候,发现有一个文件里的代码总是没有被重构。感到很蛋疼的我以为莫非是我的重构脚本出问题了?于是仔细检查,没有问题。那就是wrangler出问题了?然后查看了wrangler返回的结果,发现是在解析该文件的时候出错了,即parse的时候出现错误,返回了解析出错。好吧,那我们来调试wrangler。

wrangler代码简单分析

wrangler是用erlang写的erlang重构服务,他启动之后会在epmd注册一个wrangler服务,我们重构的时候只需要告诉他,在哪个文件的哪一行,我想要重构成什么即可。举个例子,比如我们想重明明某个变量,只需要通过erlang原生rpc调用

wrangler_refacs:rename_var(FileName, Line, Col, NewName, SearchPaths, Context, TabWidth) 

(由于版本不同,该函数名称可能会有差异)

即可完成预重构,此时会创造一个重构好的副本,而不是直接修改源文件。然后发送一个confirm指令,将重构
Legacy in the grammar
Try to use "query" as an atom in Erlang, e.g. {query, "SELECT * FROM foobar"}. What happens?
syntax error before: ','
This is because 'query' is a reserved word which was reserved for Mnemosyne queries. Never heard of Mnemosyne? That's because it's an archaic way of querying Erlang's built-in database, Mnesia, and has been replaced with Query List Comprehensions (QLC). However, it remains around for backwards compatibility.
You can't use "query" as a function name. You can't tag a tuple with "query". You can't do anything with "query" except invoke a deprecated legacy API which no one uses anymore.

实施到当前文档,也就是修改下文件名。

wrangler本身使用rebar进行编译,所以如果你

现在以重构变量名为例,他的调用过程如下:

wrangler_refacs:rename_var
  wrangler_refacs:try_refac
     wrangler_refacs:try_to_apply
       refac_rename_var:rename_var
         wrangler_ast_server:parse_annotate_file
         ....

在refac_rename_var:rename_var里面,进行了新变量名的合法性判断,然后就开始parse_annotate_file,即解析目标文件。


在对该函数进行调试之后,发现该函数在解析道query的时候出错。query这个关键字是我在mysql库里面作为sql语句执行函数引进的,该库在运行环境中是可以稳定运行的,所以至少该文件是可以通过编译并且稳定使用的。那么为什么wrangler认为query有问题呢?为了简化问题,我建了一个只有一个query函数的erl文件,调用重构函数,发现重构失败,然后将query改成其它名称,重构成功。看来query就是问题所在了。


核对query的问题

作为一个erlang的新手,从来没有听说过query在erlang里面有什么特别的应用,所以并不能理解为啥query会出错。我仔细检查了对应的parse代码,wrangler定义的query语法,完全不是我认识的erlang语法。那么query是什么呢?google了一下,找到了erlang文档里面有这么一段:

Legacy in the grammar
Try to use "query" as an atom in Erlang, e.g. {query, "SELECT * FROM foobar"}. What happens?
syntax error before: ','
This is because 'query' is a reserved word which was reserved for Mnemosyne queries. Never heard of Mnemosyne? That's because it's an archaic way of querying Erlang's built-in database, Mnesia, and has been replaced with Query List Comprehensions (QLC). However, it remains around for backwards compatibility.
You can't use "query" as a function name. You can't tag a tuple with "query". You can't do anything with "query" except invoke a deprecated legacy API which no one uses anymore.

也就是这个query关键字是erlang 以前使用的一个查询关键字,现在已经不再使用了,甚至在某个版本中还是不允许作为atom使用。而这个坑已经被修改了,query已经可以作为atom被使用了。

修复问题

现在确认了是query的问题,我们可以尝试修复这个问题。wrangler认为query是关键字,所以不允许使用,只需将query从关键字列表里移除,就可以修复问题了。

在wrangler的wrangler_scan.erl的reserved_word函数clause里面,有一个query,将其抹去,wrangler将不再认为query是关键字。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值