Я хочу использовать String.to_existing_atom в эликсире, чтобы избежать утечек памяти.
Это 100% работает на REPL:
iex(1)> defmodule MyModule do
...(1)> defstruct my_crazy_atom: nil
...(1)> end
{:module, MyModule,
<<70, 79, 82, ...>>,
%MyModule{my_crazy_atom: nil}}
Итак, теперь атом my_crazy_atom
существует. Я могу это проверить:
iex(2)> String.to_existing_atom "my_crazy_atom"
:my_crazy_atom
В сравнении с:
iex(3)> String.to_existing_atom "my_crazy_atom2"
** (ArgumentError) argument error
:erlang.binary_to_existing_atom("my_crazy_atom2", :utf8)
Но у меня есть код, который выглядит так:
defmodule Broadcast.Config.File do
defstruct channel_id: nil, parser: nil
end
Из вызова метода после запуска процесса GenServer я могу декодировать с помощью Poison's
keys: :atoms!
или даже просто позвонить
String.to_existing_atom("parser")
там же в коде и получаю ошибку:
** (Mix) Could not start application broadcast: exited in:
Broadcast.Application.start(:normal, [])
** (EXIT) an exception was raised:
** (ArgumentError) argument error
:erlang.binary_to_existing_atom("parser", :utf8)
Как ни странно, если я создам экземпляр структуры и проверю ее, проблема исчезнет!
IO.puts inspect %Broadcast.Config.File{}
String.to_existing_atom("parser")
Что тут происходит? Это что-то типа заказа?
MyModule
, а затем выполнивString.to_existing_atom("my_crazy_atom")
из другой функции в другом модуле. - person Dogbert   schedule 20.09.2017String.to_existing_atom
? Если я помещу его в функцию, а затем вызову, она будет работать без необходимости создавать экземпляр структуры. (Я не думаю, что ответ мудасобвы правильный (или, может быть, я неправильно понял вопрос.)) - person Dogbert   schedule 20.09.2017