dashbitco / nimble_csv

A simple and fast CSV parsing and dumping library for Elixir
https://hexdocs.pm/nimble_csv
772 stars 51 forks source link

Defining a parser causes the file to always be recompiled #4

Closed codebender closed 8 years ago

codebender commented 8 years ago

Is this expected? I'm pretty new to elixir but it seems like unwanted behavior. I would expect it to use the already compiled file when running the project the second time.

Example tsv.ex:

NimbleCSV.define(TSV, separator: "\t")

defmodule MyTest do
  IO.puts "loading"
end

Running the program 2 times

matthewbender ~/codebender/tsv $ iex -S mix
Erlang/OTP 19 [erts-8.0.2] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]

Compiling 1 file (.ex) loading Generated tsv app Interactive Elixir (1.3.2) - press Ctrl+C to exit (type h() ENTER for help) iex(1)> System.halt matthewbender ~/codebender/tsv $ iex -S mix
Erlang/OTP 19 [erts-8.0.2] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]

Compiling 1 file (.ex) loading Interactive Elixir (1.3.2) - press Ctrl+C to exit (type h() ENTER for help) iex(1)>

I wound't expect the 2nd "Compiling 1 file (.ex)", when no changes to any file were made between runs.

josevalim commented 8 years ago

There is something odd happening but that's rather an Elixir compiler bug. If you place each module on a different file, it works fine. So I recommend this work-around for now.

codebender commented 8 years ago

Hey @josevalim, I tried your suggestion but saw a compilation error on the second run. Here is the source code of what I tried: https://github.com/codebender/nimble_issue

As you see, I moved the NimbleCSV.define into its own file, parser.ex. The main file parses a tab delimited string with the parser.

Here is what I see when I run the app the 1st time:

matthewbender ~/codebender/nimble_issue $ iex -S mix
Erlang/OTP 19 [erts-8.0.2] [source] [64-bit] [smp:8:8] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]

Compiling 2 files (.ex)
[["john", "27"]]
Interactive Elixir (1.3.2) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)>

It seems to work as expected! 😸 !

Here is what I see when I run the app the 2nd time:

matthewbender ~/codebender/nimble_issue $ iex -S mix
Erlang/OTP 19 [erts-8.0.2] [source] [64-bit] [smp:8:8] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]

Compiling 1 file (.ex)

== Compilation error on file lib/nimble_issue.ex ==
** (UndefinedFunctionError) function TSV.parse_string/1 is undefined (module TSV is not available)
    TSV.parse_string("name\tage\njohn\t27")
    lib/nimble_issue.ex:2: (module)
    (stdlib) erl_eval.erl:670: :erl_eval.do_apply/6

What's going on with the second run? 😿

Thanks for the help BTW!

josevalim commented 8 years ago

Yes, that's definitely on the Elixir compiler. Let's leave it on the same file for now and we will investigate. :D

josevalim commented 8 years ago

Fixed in Elixir master and v1.3 branches. thank you for the report!

codebender commented 8 years ago

@josevalim Glad to help! πŸ˜ΈπŸ”

ayayalar commented 8 years ago

I am still seeing this issue in 1.3.2. I assume it'll be fixed in the next version?

josevalim commented 8 years ago

Yes, it has not been released yet. :)

ayayalar commented 8 years ago

Thanks @josevalim!