Reputation: 67
When I want to compile a simple file.erl
file, I got the error message.
$ erlc file.erl
/opt/erlang17.5/lib/kernel-3.2/include/file.hrl:34: type date_time() undefined
Below is the content of 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]).
It seems nobody reported this kind of issue, is there anything wrong with what I did?
Upvotes: 0
Views: 695
Reputation: 20004
It's instructive to investigate the root cause of the compilation problem. The compiler emits this error:
/opt/erlang17.5/lib/kernel-3.2/include/file.hrl:34: type date_time() undefined
Looking at line 34 of file.hrl
we see:
ctime :: file:date_time() | non_neg_integer(),
This is a type specifier for the ctime
field of the #file_info{}
record. It states that ctime
can hold a value of either the file:date_time()
type or of the non_neg_integer()
type.
The error message complains specifically about the date_time()
type because its scope indicates that it's defined in the file
module. In this case, the file
module is the one being defined and compiled, and it's hiding the standard one provided by the Erlang/OTP kernel
application. The standard file
module defines its date_time()
type as follows:
-type date_time() :: calendar:datetime().
The file
module we're trying to compile, though, does not. What happens if we add this type definition?
-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]).
Compiling this version containing the added type definition now works:
$ erlc file.erl
$
We've fixed the compilation error, so let's try to use our compiled module. We start an 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 ()
We can see in the error message that an attempt to call file:path_eval/2
failed because it's not defined. Because our file
module hides the standard one but doesn't supply all the same functions, we can't even start up an Erlang shell as long as our file
module hides the standard one.
Clearly, choosing a different name for the module is necessary for more than just fixing the original compilation error.
Upvotes: 6
Reputation: 116
Your code is right, the problem is with filename. Erlang has library "file", so you cannot use this filename. Change it (don't forget to modify source) and everything should be fine.
Upvotes: 1