sribe
Given the output of IO.inspect on a map, is there any way to parse that string back into a map?
Given the output of IO.inspect on a map, is there any way to parse that string back into a map?
For a one-shot hack, one could put them into source files and compile. For ongoing parsing out of a log, one could JSON encode them instead. But assume there’s a pile of maps written out by IO.inspect: is there a way to rehydrate them directly?
A tiny bit of context: I actually thought I had JSON in the files, but lolz, I do not.
Most Liked
al2o3cr
One gotcha: inspect will truncate output by default if the maps are large. For instance:
0..100 |> Enum.with_index() |> Map.new() |> inspect() |> Code.eval_string()
fails (on my machine anyways) with:
warning: variable "..." does not exist and is being expanded to "...()", please use parentheses to remove the ambiguity or change the variable name
nofile:1
** (CompileError) nofile:1: undefined function .../0 (there is no such import)
(elixir 1.13.4) lib/code.ex:404: Code.validated_eval_string/3
lud
For a single map you can do this:
%{a: 1} |> inspect |> Code.eval_string() |> elem(0)
Now if you have more, you will have to find a way to split the string into valid chunks of code.
Now if this for a test or a quick made tool it’s fine but otherwise consider that eval is evil and be sure that there is no proper way of doing what you want before eval’ing code.
sribe
Thank you, eval_string is what I was missing.
I do have more, and I am already splitting them–I got to the part where I tried to parse them after splitting, Jason.decode kept failing, I looked closer and realized D’OH! NOT JSON!! ![]()
Nicd
Another gotcha is that there’s no requirement for the inspect output to be valid Elixir. Many structs are inspected as something like #Foo<something> instead of %Foo{something}. It may not be feasible to parse your inspect output at all.
Obligatory note, evaling strings is very dangerous and a wide open invitation for remote code execution, if an attacker can control the inputs.
msimonborg
You can also Code.eval_file if it was written to a file.
File.write!("maps.txt", inspect([%{foo: :bar}, %{biz: :baz}]))
# => :ok
"maps.txt"
|> Code.eval_file()
|> elem(0)
# => [%{foo: :bar}, %{biz: :baz}]
Again, eval is very dangerous! Only use it if you trust the content 100%. Sounds like maybe you wrote the files though but just be careful.







