Fl4m3Ph03n1x

Fl4m3Ph03n1x OP

Sorry, that was a mistake on my side when creating the reply, the code itself does not suffer from this ailment.
(meaning the error you see is the error I get without the =)

Is the only option here to create a helper module ?

0
Post #11
LostKobrakai

LostKobrakai

You can use anonymous functions as well, but a module cannot use it’s own functions at compile time, as those functions are not available before the complete module is compiled. It’s a classic chicken-egg type problem.

1
Post #12
michallepicki

michallepicki

@Fl4m3Ph03n1x Another issue in your code is that you can’t do

@sports
  @compiled_csv_data
  |> ...

you need to do

@sports
  csv_data
  |> ...

And turns out that in Elixir 1.5 also when declaring the @sports module attribute, to be able to use it in guards you need to do it in two steps. This works:

  sports =
    csv_data
    |> Stream.map(fn {sport, _country, _league} -> sport end)
    |> Enum.filter(fn sport -> sport != "" end)

  @sports sports

  def hard_sport?(sport) when sport in @sports, do: false
1
Post #13
lud

lud

Yes I checked, it is indeed only needed for macros.

0
Post #14
eksperimental

eksperimental

Sorry, you are right.
It is absolutely not needed, you can get away with it by storing the value at compile time in an attribute and invoke it inside a function.

Something like this based on Michal’s code.

defmodule SportsCsvReader do
  @sports_data         :my_app
    |> :code.priv_dir()
    |> Path.join("awesome_csv.csv")
    |> File.stream!()
    |> CSV.decode!(headers: false, separator: ?;)
    |> Stream.map(&List.to_tuple/1)
    |> Stream.uniq()
    |> Enum.map(fn {sport, country, league} ->
      {String.trim(sport), String.trim(country), String.trim(league)}
    end)

  def sports_data(), do: @sports_data

  def extract_sports(sports_data) do
    sports_data
    |> Enum.map(fn {sport, _country, _league} -> sport end)
    |> Enum.filter(fn sport -> sport != "" end)
  end

  def extract_countries(sports_data) do
    sports_data
    |> Enum.map(fn {_sport, country, _league} -> country end)
  end
end

My point is that you only need to parse the CSV once, and that is at compile time.

1
Post #15
— All posts loaded —