无法使用文件模块编译Erlang文件
Can not compile Erlang file using file module
当我想编译一个简单的file.erl
文件时,我得到了错误信息。
$ erlc file.erl
/opt/erlang17.5/lib/kernel-3.2/include/file.hrl:34: type date_time() undefined
以下是file.erl
的内容
-module(file).
-include_lib("kernel/include/file.hrl").
-export([file_info/1]).
file_info(Dir) ->
{ok, F} = file:read_file_info(Dir),
io:format("~p~n", [F#file_info.type]).
好像没有人反映过这种问题,我做的有什么问题吗?
你的代码是正确的,问题出在文件名上。 Erlang 有库 "file",所以你不能使用这个文件名。更改它(不要忘记修改源),一切都应该没问题。
调查编译问题的根本原因很有帮助。编译器发出此错误:
/opt/erlang17.5/lib/kernel-3.2/include/file.hrl:34: type date_time() undefined
查看 file.hrl
的第 34 行,我们看到:
ctime :: file:date_time() | non_neg_integer(),
这是 #file_info{}
记录的 ctime
字段的类型说明符。它声明 ctime
可以保存 file:date_time()
类型或 non_neg_integer()
类型的值。
错误消息特别抱怨 date_time()
类型,因为它的范围表明它是在 file
模块中定义的。在本例中,file
模块是被定义和编译的模块,它隐藏了 Erlang/OTP kernel
应用程序提供的标准模块。标准 file
模块定义其 date_time()
类型如下:
-type date_time() :: calendar:datetime().
我们试图编译的 file
模块没有。如果我们添加这个类型定义会发生什么?
-module(file).
-type date_time() :: calendar:datetime().
-include_lib("kernel/include/file.hrl").
-export([file_info/1]).
file_info(Dir) ->
{ok, F} = file:read_file_info(Dir),
io:format("~p~n", [F#file_info.type]).
现在可以编译包含添加的类型定义的版本:
$ erlc file.erl
$
我们已经修复了编译错误,所以让我们尝试使用我们编译的模块。我们启动一个 Erlang shell:
$ erl
Erlang/OTP 18 [erts-7.0] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:10] [hipe] [kernel-poll:false]
{"init terminating in do_boot",{undef,[{file,path_eval,[[".","/Users/user"],".erlang"],[]},{c,f_p_e,2,[{file,"c.erl"},{line,481}]},{init,eval_script,8,[]},{init,do_boot,3,[]}]}}
Crash dump is being written to: erl_crash.dump...done
init terminating in do_boot ()
我们可以在错误消息中看到尝试调用 file:path_eval/2
失败,因为它未定义。因为我们的 file
模块隐藏了标准模块但不提供所有相同的功能,所以只要我们的 file
模块隐藏标准模块,我们甚至无法启动 Erlang shell .
显然,为模块选择不同的名称不仅仅是为了修复原始编译错误。
当我想编译一个简单的file.erl
文件时,我得到了错误信息。
$ erlc file.erl
/opt/erlang17.5/lib/kernel-3.2/include/file.hrl:34: type date_time() undefined
以下是file.erl
的内容-module(file).
-include_lib("kernel/include/file.hrl").
-export([file_info/1]).
file_info(Dir) ->
{ok, F} = file:read_file_info(Dir),
io:format("~p~n", [F#file_info.type]).
好像没有人反映过这种问题,我做的有什么问题吗?
你的代码是正确的,问题出在文件名上。 Erlang 有库 "file",所以你不能使用这个文件名。更改它(不要忘记修改源),一切都应该没问题。
调查编译问题的根本原因很有帮助。编译器发出此错误:
/opt/erlang17.5/lib/kernel-3.2/include/file.hrl:34: type date_time() undefined
查看 file.hrl
的第 34 行,我们看到:
ctime :: file:date_time() | non_neg_integer(),
这是 #file_info{}
记录的 ctime
字段的类型说明符。它声明 ctime
可以保存 file:date_time()
类型或 non_neg_integer()
类型的值。
错误消息特别抱怨 date_time()
类型,因为它的范围表明它是在 file
模块中定义的。在本例中,file
模块是被定义和编译的模块,它隐藏了 Erlang/OTP kernel
应用程序提供的标准模块。标准 file
模块定义其 date_time()
类型如下:
-type date_time() :: calendar:datetime().
我们试图编译的 file
模块没有。如果我们添加这个类型定义会发生什么?
-module(file).
-type date_time() :: calendar:datetime().
-include_lib("kernel/include/file.hrl").
-export([file_info/1]).
file_info(Dir) ->
{ok, F} = file:read_file_info(Dir),
io:format("~p~n", [F#file_info.type]).
现在可以编译包含添加的类型定义的版本:
$ erlc file.erl
$
我们已经修复了编译错误,所以让我们尝试使用我们编译的模块。我们启动一个 Erlang shell:
$ erl
Erlang/OTP 18 [erts-7.0] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:10] [hipe] [kernel-poll:false]
{"init terminating in do_boot",{undef,[{file,path_eval,[[".","/Users/user"],".erlang"],[]},{c,f_p_e,2,[{file,"c.erl"},{line,481}]},{init,eval_script,8,[]},{init,do_boot,3,[]}]}}
Crash dump is being written to: erl_crash.dump...done
init terminating in do_boot ()
我们可以在错误消息中看到尝试调用 file:path_eval/2
失败,因为它未定义。因为我们的 file
模块隐藏了标准模块但不提供所有相同的功能,所以只要我们的 file
模块隐藏标准模块,我们甚至无法启动 Erlang shell .
显然,为模块选择不同的名称不仅仅是为了修复原始编译错误。