michaelwa
Converting Erlang Record into Maps and Maps into Erlang Record
Hello All,
I am missing the boat on what I think should be a simple conversion process.
Given:
defmodule User do
require Record
Record.defrecord(:user, name: "meg", age: "25")
end
Record to map is fairly straightforward:
user_map = Enum.into(user(record), %{})
But this is not optimal because for every ‘defrecord’ declaration you would need to create a conversion function new ‘defrecord’ type. E.g. “user” above. But at least there is a solution.
However, for the return trip from map to record I do not see any path.
This works:
record = user([age: 45, name: "Mike"])
# -> {:user, "Mike", 45}
But this does not:
attrs = [age: 45, name: "Mike"]
record = user(attrs)
** !?!?!? **
I did get this to work but this seems just a tiny bit convoluted.
defmodule Test.This do
def map_to_record(map) do
[ hd | _ ] = Enum.map(
[map],
fn %{age: age, name: name}
->
{:user, age, name}
end)
hd
end
end
And again this requires a custom function for every ‘defrecord’ declaration to move between maps to records.
Thanks in advanced!
Most Liked
al2o3cr
Records on the Erlang side are a compile-time-only concern - at runtime, they are just tuples. In Elixir the macros created by defrecord contain the information necessary to understand where name is in {:user, "meg", "25"}.
That’s also why your “reverse” case fails: the argument to user/1 needs to be a compile-time keyword list, but user(attrs) happens at runtime.
You’d need to write out the list explicitly:
attrs = [age: 45, name: "Mike"]
record = user(age: attrs[:age], name: attrs[:name])







