I'm currently very interested in learning Elixir and my typical approach of learning a new language is to build simple programs with it.
So I decided to write a (very simple) grep-like program (or module) which is shown here:
defmodule LineMatch do
def file(s, path) do
case File.open(path, [:read]) do
{:ok, fd} -> match s, fd
{_, error} -> IO.puts "#{:file.format_error error}"
end
end
defp match(s, fd) do
case IO.read fd, :line do
{:error, error} -> IO.puts("oh noez! Error: #{error}")
line -> match(s, line, fd)
end
end
defp match(s, line, fd) when line !== :eof do
if String.contains?(line, s) do
IO.write line
end
match(s, IO.read(fd, :line), fd)
end
defp match(_, _line, _) when _line === :eof do
end
end
This is most probably not the most elegant way to do it and I'm also quite new to functional programming, so I didn't expect it to be super fast. But it is not only not fast, it is actually super slow. So slow that I probably did some super obvious mistake.
Can anyone tell me, what it is and how to make it better?
I typically test the code with a seperate .exs file like
case System.argv do
[searchTerm, path] -> LineMatch.file(searchTerm, path)
_ -> IO.puts "Usage: lineMatch searchTerm path"
end