*21 Apr 2020* Sometimes you might need to execute code dynamically based - for instance - on the name of a module, akin to code reflection on other languages. In Elixir one way this can be achieved is by using Erlang's `:code` module. As an example, say you want to run a function in a module named `MyProject.Foo`. ### Find that module The first thing we need to do is to find the module: ` ``` def find_module(name) do :code.all_loaded() |> Enum.map(&elem(&1, 0)) |> Enum.find(fn module -> module_name = Atom.to_string(module) String.starts_with?(module_name, "Elixir.#{name}") and !String.ends_with?(module_name, "Test") end) end ``` ` You might notice two things there: 1. all modules in Elixir start with `Elixir.` and 2. i am excluding a potential test module that might have the same name as the module we want to run the code on. ### Run them codes Now we need to be able to execute functions on our module. For that we can use the `apply` function from the Kernel: ` ``` case find_module(module_name) do nil -> {:error, "module #{module_name} not found"} module -> apply(module, function, args) end ``` ` ### A concrete example ` ``` defmodule MyProject.Foo do def bar(message) do IO.puts("Hello #{message}") end end defmodule MyProject.Runtime do def find_module(name) do :code.all_loaded() |> Enum.map(&elem(&1, 0)) |> Enum.find(fn module -> module_name = Atom.to_string(module) String.starts_with?(module_name, "Elixir.#{name}") and !String.ends_with?(module_name, "Test") end) end def execute_module_function(module_name, function, args \\ []) do case find_module(module_name) do nil -> {:error, "module #{module_name} not found"} module -> apply(module, function, args) end end end MyProject.Runtime.execute_module_function("MyProject.Foo", :bar, ["world"]) MyProject.Runtime.execute_module_function("MyProject.NonExisting", :bar, ["world"]) ``` ` Happy coding! [[tags/code|code]] [[tags/dynamic|dynamic]] [[tags/elixir|elixir]] [[tags/execution|execution]] [[tags/module|module]] [[tags/reflection|reflection]]