[erlang-questions] filelib:is_* is missing something necessary.

Zoltan Lajos Kis kiszl@REDACTED
Sat Nov 28 16:29:55 CET 2009

Michael Richter wrote:
> I found out that the file type predicates in *filelib* (*is_file/1*, *
> is_dir/1*, *is_regular/1*) have a little quirk that makes them not that
> useful for my purposes.  Specifically they treat symbolic links to files as
> files and symbolic links to directories as directories instead of flagging
> each respectively as symlinks.
> It seems to me that they're implemented in terms of
> *read_file_info/1*instead of
> *read_link_info/1* and I was wondering if it might not be possible to make
> one of the following changes, depending on what people in the community
> found most useful (I'm easy either way, personally):
>    1. Change the return values such that, say, *is_file/1* returns *true* if
>    the named file is a straight file, but returns *symlink* if it is a
>    symbolic link *to a file*.  (In any other situation -- directory, symlink
>    to directory, special file, etc. -- it would still return *false*.)
>    2. Add a predicate *is_symlink/1* so that I can first check if
>    something's a directory and then follow through with a check if it's a
>    symbolic link to one.
> Currently I've just rewritten the predicates for my code, but in general I
> prefer to use system libraries wherever possible so I'd really like to see
> one of the two above approaches (or perhaps a third, superior one) written
> in.  My predicate for *is_symlink/1* looks like this:
> is_symlink(Name) ->
>     case file:read_link_info(Name) of
>         {ok, FileInfo} -> FileInfo#file_info.type =:= symlink
>     end.
> It's not a particularly Earth-shattering change for option 2.  Option 1
> could look something like this only without the fugliness of my quick hack.:
> is_regular(Name) ->
>     case file:read_file_info(Name) of
>         {ok, #file_info{type = regular}} ->
>             case file:read_link_info(Name) of
>                 {ok, #file_info{type = symlink}} -> symlink;
>                 _                                -> true
>             end;
>         _                                -> false
>     end.
An is_xyz function returning anything other than 'true' or 'false' is 
certainly against the "least astonishment" principle, so I would not 
take that road...

More information about the erlang-questions mailing list