Erlang Nitrogen入门教程项目运行失败,编译遇error/3函数名冲突问题求助
make rel_inets Due to Ambiguous error/3 BIF Call (Erlang 24.0.1) Problem Description
我正在跟着Nitrogen项目的入门教程操作,但浏览器访问localhost:8000时项目无法启动。排查后发现问题出在执行make rel_inets命令时,出现了函数名冲突的编译错误,具体日志如下:
/home/david/programming/erlang/nitrogen/nitrogen/rel/nitrogen/lib/erlware_commons/src/ec_cmd_log.erl:160:5: ambiguous call of overridden auto-imported BIF error/3 - use erlang:error/3 or "-compile({no_auto_import,[error/3]})." to resolve name clash
Compiling /home/david/programming/erlang/nitrogen/nitrogen/rel/nitrogen/lib/erlware_commons/src/ec_cmd_log.erl failed: ERROR: compile failed while processing /home/david/programming/erlang/nitrogen/nitrogen/rel/nitrogen/lib/erlware_commons: rebar_abort
make[4]: *** [Makefile:12: compile] Error 1
我已经安装了最新的Erlang 24.0.1版本,但问题依然存在,请问该如何解决这个冲突问题?
Solution
这个问题是因为Erlang 24新增了erlang:error/3这个内置函数(BIF),而erlware_commons库的ec_cmd_log模块恰好也定义了同名的error/3函数,导致了命名冲突。这里提供两种直接可行的解决办法:
方法1:添加编译指令禁用自动导入
这是最直接的解决方式,告诉编译器不要自动导入Erlang的error/3,优先使用模块自身的定义:
- 打开文件
/home/david/programming/erlang/nitrogen/nitrogen/rel/nitrogen/lib/erlware_commons/src/ec_cmd_log.erl - 在模块声明
-module(ec_cmd_log).的下方,添加一行编译配置:-compile({no_auto_import,[error/3]}). - 保存文件后,重新执行
make rel_inets命令即可完成编译
方法2:显式指定函数的调用来源
如果不想修改编译选项,也可以直接修改冲突代码的调用方式:
- 打开
ec_cmd_log.erl文件,定位到第160行的error/3调用 - 如果要调用模块自己实现的
error/3,保持代码不变即可;如果需要调用Erlang内置的版本,修改为erlang:error(Arg1, Arg2, Arg3)(替换成原代码的参数) - 保存修改后重新执行编译命令
备选方案:降级Erlang版本
如果当前使用的Nitrogen版本尚未适配Erlang 24,你也可以暂时降级到Erlang 23系列版本(Erlang 23没有erlang:error/3这个BIF),这样就能直接避开这个冲突,等Nitrogen发布兼容Erlang 24的更新后再升级。
内容的提问来源于stack exchange,提问作者Bucephalus

