dynamic module load elixir

dynamic - Elixir-Método de llamada en el módulo por String-name



module load (3)

Soy bastante nuevo en Elixir y en los lenguajes de programación funcionales en general.

En Elixir, quiero llamar a una función específica en Módulos, dado el nombre del Módulo como Cadena.

Tengo el siguiente código (muy malo) funcionando, que hace lo que quiero:

module_name = elem(elem(Code.eval_file("module.ex", __DIR__), 0), 1) apply(module_name, :helloWorld, [])

Esto (al menos tal como lo entiendo) compila el módulo (ya compilado) de module.ex en el directorio actual. Estoy extrayendo el nombre de los módulos (no como una cadena, no sé qué tipo de datos es en realidad) de las dos tuplas y ejecuto el método helloWorld en él.

Hay dos problemas con este código:

  1. Imprime una advertencia como redefining module Balance . Ciertamente no quiero que eso suceda en producción.

  2. AFAIK este código compila module.ex . Pero como module.ex ya está compilado y cargado, no quiere que eso suceda.

No necesito llamar a métodos en estos módulos por nombre de archivo, el nombre de módulo también estaría bien. Pero tiene que hacerlo por dinámica, ej. al ingresar "Libro" en la línea de comando, después de verificar si el módulo existe, llame a la función Book.helloWorld .

Gracias.


Bueno, ahí es donde pedir ayuda: lo sabrás tú mismo en el momento en que lo pidas. ;)

Simplemente usando apply(String.to_existing_atom("Elixir.Module"), :helloWorld, []) ahora. (tal vez el nombre "Módulo" no está permitido, no lo sé)


También tenga en cuenta que el nombre de un módulo es un átomo, por lo que String.to_existing_atom no suele ser necesario. Considera este código:

defmodule T do def first([]), do: nil def first([h|t]), do: h end

En este caso, simplemente puede hacer la solicitud de esta manera:

apply(T,:first,[[1,2,3]]) #=> 1

O este ejemplo (la lista a continuación es el módulo de la lista Elixir):

apply(List,:first,[[1,2,3]]) #=> 1

Quiero decir que si conoces el nombre del módulo, no es necesario pasarlo como una cadena y luego convertir la cadena a un átomo existente. Simplemente use el nombre sin comillas.


Tenga en cuenta que siempre necesita agregar un prefijo a sus módulos con "Elixir".

defmodule Test do def test(text) do IO.puts("#{text}") end end apply(String.to_existing_atom("Elixir.Test"), :test, ["test"])

imprime "prueba" y devuelve {: ok}