I have several functions defined as private to the module. In another private function in that module I want to take a string parameter and pass it to apply/3 to call one of those private functions via String.to_existing_atom/1. For instance:
defmodule Foo do
defp bar do
IO.puts("bar")
end
defp baz(s) do
apply(Foo, String.to_existing_atom(s), [])
end
end
When I call Foo.baz("bar") I get the error Foo.bar is undefined or private. I would not have expected this since baz is in the same module. Am I doing something wrong or is this expected behavior? If so, is this something a macro would mitigate?
If you look at the erlang documentation for apply/3 it says:
Returns the result of applying Function in Module to Args. The applied function must be exported from Module.
Which explains why you see the error - dispatching starts with the Module, looks up its exported functions and then applies.
I think (but have not tested) that apply/2 may work in this case - at least the the documentation doesn’t suggest otherwise. ie: apply(String.to_existing_atom(s), [])
I will submit a PR to include the must be a public function note to Elixir’s documentation.