Elixir/Erlang 中的命名函数是否有相当于 __MODULE__ 的函数?

问题描述 投票:0回答:4

是否有一个相当于检索函数名称的方法,就像

__MODULE__
检索 Elixir/Erlang 中的模块名称一样?

示例:

defmodule Demo do
  def home_menu do
    module_name = __MODULE__
    func_name = :home_menu 
    # is there a __FUNCTION__
  end
End

已编辑

所选答案有效,

但是使用 apply/3 调用返回的函数名称会产生此错误:

[error] %UndefinedFunctionError{arity: 4, exports: nil, function: :public_home, module: Demo, reason: nil}

我有一个功能:

defp public_home(u, m, msg, reset) do

end

相关函数将严格在其模块内调用。

有没有办法在自己的模块内通过名称动态调用私有函数?

erlang elixir
4个回答
30
投票
▶ defmodule M, do: def m, do: __ENV__.function  
▶ M.m                                                 
#⇒ {:m, 0}

本质上,

__ENV__
结构包含您可能需要的一切。


4
投票

是的,有。在 Erlang 中,有几个预定义宏,它们应该能够提供您需要的信息:

% The name of the current function
?FUNCTION_NAME

% The arity of the current function (remember name alone isn't enough to identify a function in Erlang/Elixir)
?FUNCTION_ARITY 

% The file name of the current module
?FILE 

% The line number of the current line
?LINE 

来源:http://erlang.org/doc/reference_manual/macros.html#id85926


2
投票

为了添加 Aleksei 的答案,这里是一个宏示例,

f_name()
,它仅返回函数的名称。

所以如果你在函数中使用它,就像这样:

def my_very_important_function() do
   Logger.info("#{f_name()}: about to do important things")
   Logger.info("#{f_name()}: important things, all done")
end

您将得到类似于以下的日志语句:

my_very_important_function: about to do important things
my_very_important_function: important things, all done

详情:

以下是宏的定义:

defmodule Helper do
  defmacro f_name() do
    elem(__CALLER__.function, 0)
  end
end

__CALLER__就像__ENV__,但它是调用者的环境。)

以下是如何在模块中使用宏:

defmodule ImportantCodes do
  require Logger
  import Helper, only: [f_name: 0]

  def my_very_important_function() do
     Logger.info("#{f_name()}: doing very important things here")
  end
end

0
投票
__ENV__.function |> elem(0) 

结果将显示您当前所在函数的名称。

© www.soinside.com 2019 - 2024. All rights reserved.