Как упоминалось в комментариях, вы не должны использовать Code.eval_string
. Но есть способ безопасно преобразовать ваш код в структуру Elixir, используя модуль Code
:
ex(1)> encoded = "%Sample.Struct{list: [], total: \"0.00\", day: 6, id: \"8vfts6\"}"
"%Sample.Struct{list: [], total: \"0.00\", day: 6, id: \"8vfts6\"}"
Во-первых, получите AST из строки, но используйте сопоставление с образцом, чтобы убедиться, что это именно та структура, которую вы ищете ({:__aliases__, _, [:Sample, :Struct]}
). Весь другой (потенциально вредоносный) код не будет соответствовать этому совпадению:
iex(2)> {:ok, {:%, _, [{:__aliases__, _, [:Sample, :Struct]}, {:%{}, _, keymap}]} = ast} = Code.string_to_quoted(encoded)
{:ok,
{:%, [line: 1],
[{:__aliases__, [line: 1], [:Sample, :Struct]},
{:%{}, [line: 1], [list: [], total: "0.00", day: 6, id: "8vfts6"]}]}}
Здесь у вас есть полная структура ast
для вас, и keymap
. Теперь у вас может возникнуть соблазн использовать eval_quoted
с AST, чтобы получить нужную вам структуру:
iex(3)> {struct, _} = Code.eval_quoted(ast)
{%Sample.Struct{day: 6, id: "8vfts6", list: [], total: "0.00"}, []}
iex(4)> struct
%Sample.Struct{day: 6, id: "8vfts6", list: [], total: "0.00"}
Но это все еще небезопасно! Кто-то может поместить в строку функцию, вызывающую побочный эффект, например "%Sample.Struct{list: IO.puts \"Something\"}"
, которая будет выполняться во время оценки. Поэтому вам нужно сначала проверить keymap
, если они содержат безопасные данные.
Или вы можете просто использовать keymap
напрямую, ничего не оценивая:
iex(5)> struct(Sample.Struct, keymap)
%Sample.Struct{day: 6, id: "8vfts6", list: [], total: "0.00"}
person
Grych
schedule
29.11.2017
inspect
? Строка, возвращаемая inspect, не обязательно содержит правильный синтаксис Elixir, хотя в этом примере он есть. - person Dogbert   schedule 29.11.2017:erlang.term_to_binary
и:erlang.binary_to_term
. В вашем примере вам нужноeval_string
это, что, как сказал @Dogbert, не очень хорошая идея по соображениям безопасности (и не только). - person Grych   schedule 29.11.2017