I’m learning Erlang. I’ll get into “why” in some other post - the purpose here is to share my first sample program and solicit feedback. The purpose of the program is to start print the contents of a file system from the indicated point downwards (ignoring symlinks).

The application has a single module, walker, which exports walk/1. The argument to walk/1 is the starting path. For example: > walker:walk("/home").

This method prints the path name, determines the type of the current path (file, directory or symlink), and then IFF the path is a directory it calls filelib:wildcard to get the children of the path and repeats the process on them.




is_symlink(Path) ->
	case file:read_link_info(Path) of
		{ok, #file_info{type = symlink}} ->
		_ ->

file_type(Path) ->
	IsRegular = filelib:is_regular(Path),
	case IsRegular of
		true ->
		false ->
			case is_symlink(Path) of
				true ->
				false ->

walk(Path) ->
	io:format("~s~n", [Path]),

	FileType = file_type(Path),
	case FileType of
		file ->
		symlink ->
		directory ->
			Children = filelib:wildcard(Path ++ "/*"),
			lists:foreach(fun(P) -> walk(P) end, Children)

My questions about this module are:

  1. Does calling walk(P) in a foreach prevent tail recursion optimizations?
  2. Where I have “case FileType of” (in walk/1) is there a more succinct way to express that?
  3. Why doesn’t read_file_info ever return file_info#type==symlink?
  4. How should this have really been done?

I’ll be working on answering #1-3 on my way to learning #4 - but if you have any feedback I would love to hear it.

The next step is to make this message based and have the walk/1 method send messages to a consumer who will do the printing.

The next-next step is to RabbitMQ and setup one producer and three consumers - one for files, one for directories and one for symlinks. The walk/1 method will no longer print the file info but rather send the appropriate message and let the consumers print the messages.