The following code is supposed to read a file and create an Item
record for each line:
defmodule Ship do
defrecord Item, product_code: 0, quantity: 0, destination: ""
def load_data do
File.read!("data")
|> String.split
|> Enum.map &(String.split &1, ",")
|> Enum.map &(list_to_item &1)
end
defp list_to_item([pc, q, d | []]) do
{parsed_q, _} = Integer.parse q
Item.new product_code: pc, quantity: parsed_q, destination: d
end
end
There is a data
file with the following content:
1,100,London
1,30,Lisbon
3,2,Braga
The problem is, when I execute the load_data function, it looks like the last call to Enum.map is trying to call the parent function (load_data) recursively, and throwing a BadArityError
.
The output is as follows:
iex(1)> Ship.load_data
** (BadArityError) #Function<0.127338698/1 in Ship.load_data/0> with arity 1 called with 2 arguments ({:cont, []}, #Function<30.103209896/2 in Enum.map/2>)
(elixir) lib/enum.ex:2000: Enumerable.Function.reduce/3
(elixir) lib/enum.ex:879: Enum.map/2
ship.ex:8: Ship.load_data/0
The interesting part is that if I change the load_data
function to:
def load_data do
list = File.read!("data")
|> String.split
|> Enum.map &(String.split &1, ",")
Enum.map list, &(list_to_item &1)
end
It works as expected:
iex(2)> Ship.load_data
[Ship.Item[product_code: "1", quantity: 100, destination: "London"],
Ship.Item[product_code: "1", quantity: 30, destination: "Lisbon"],
Ship.Item[product_code: "3", quantity: 2, destination: "Braga"]]
So, any idea on where is the error is coming from in the first version? Aren't they supposed to be equivalent?
Btw, I'm using Elixir 0.12.4.