如何将字符串转换为Elixir中的函数

时间:2016-02-02 15:07:11

标签: elixir

我需要将一些函数应用于值的映射。 在最坏的情况下,函数大约是900函数,因此我将它们创建为数据库中的记录并立即将它们加载到地图中。这样我可以创建一个管理页面来管理所有转换公式...有一天......

现在我喜欢他们

conversion=%{"0":"Tools.Myfunc1/1","1":"Tools.Myfunc2/1",etc...}

然后我需要在map语句中应用/执行它们。

问题是它们是字符串,我得到了这个错误

|>Stream.zip(conversion) |>Enum.map( fn {rawValue, formula} -> convertUsing(rawValue,formula) end) 期待一个函数,得到“myModule.Myfunc / 1”

def convertUsing(value,formula) do
        {h,form}=formula
            value
            |>ieee
            |>form.()
     end

2 个答案:

答案 0 :(得分:6)

您可以添加&,然后使用Code.eval_string/1来评估字符串的内容。这将为您提供所需的捕获功能:

defmodule Conversion do
  def convert_using(value, conversions) do
    conversions
    |> Enum.map(&string_to_fun/1)
    |> Enum.reduce(value, &apply(&1, [&2]))
  end

  defp string_to_fun(str) do
    {fun, _} = Code.eval_string("&#{str}")
    fun
  end
end

然后你可以这样做:

defmodule Tools do
  def piratize(str), do: "#{str} arr!"
  def upcase(str), do: String.upcase(str)
end

"Hello, world!"
|> Conversion.convert_using(["Tools.piratize/1", "Tools.upcase/1"])
|> IO.puts

# HELLO, WORLD! ARR!

您可能希望将允许的函数限制为仅包含琐碎转换的特定模块,否则可能会带来一些安全风险。例如:

defp string_to_fun(str) do
  {fun, _} = Code.eval_string("&Tools.#{str}")
  fun
end

然后只需将"upcase/1"等存储在数据库中。

答案 1 :(得分:0)

Kernal.applyString.to_atom结合使用对您有帮助吗?这将要求您在由apply调用的模块中实现该功能。

apply(<Module Name>, <:string_converted_to_atom>, [<args>])