在ExProf中,Elixir函数名称在编译后打印出我假设的Erlang名称。一个例子是
Enum.reduce/3
打印为
'Elixir.Enum':'-reduce/3-lists^foldl/2-0-'/3
如何解析此字符串? -lists^foldl/2-0-
部分来自哪里?为什么有多个/3
?为什么有些名称-
有前缀? ^
是什么意思?为什么2-0-
?
答案 0 :(得分:1)
如何解析此字符串?
'Elixir.Enum':'-reduce/3-lists^foldl/2-0-'/3
是Erlang中的函数引用语法,引用模块-reduce/3-lists^foldl/2-0-
中名为Elixir.Enum
的函数,其中arity为3,类似于Elixir中的&Enum."-reduce/3-lists^foldl/2-0-"/3
。
-lists^foldl/2-0-
部分来自哪里?
-$fn/$arity-$something-$count-
是Erlang在stacktraces中返回的名称(显然是剖析输出),用于$fn/$arity
中定义的匿名函数。通常,您会看到-main/0-fun-0-
之类的内容,例如$something == "fun"
,例如:
defmodule Foo do
def main do
try do
(fn -> raise("foo") end).()
rescue
_ -> IO.inspect System.stacktrace
end
end
end
打印:
[{Foo, :"-main/0-fun-0-", 0, [file: 'foo.ex', line: 4]},
{Foo, :main, 0, [file: 'foo.ex', line: 4]},
{:erl_eval, :do_apply, 6, [file: 'erl_eval.erl', line: 670]},
{:elixir, :erl_eval, 3, [file: 'src/elixir.erl', line: 223]},
{:elixir, :eval_forms, 4, [file: 'src/elixir.erl', line: 211]},
{Code, :eval_string, 3, [file: 'lib/code.ex', line: 168]},
{Kernel.CLI, :wrapper, 1, [file: 'lib/kernel/cli.ex', line: 437]},
{Enum, :"-map/2-lists^map/1-0-", 2, [file: 'lib/enum.ex', line: 1184]}]
只是你不太可能在Elixir的默认错误消息中看到-fun-
个,因为它们是normalized,在这种情况下是anonymous fn/0 in Foo.main/0
(这就是为什么我打印了通过明确调用System.stacktrace/0
来进行堆栈跟踪。
那么lists^foldl/2
来自哪里?这是generated by sys_core_fold_lists
,模块called by sys_core_fold
,用于定义inline_list_funcs
编译属性(Elixir does do that中的Enum
模块)的模块,其中“内联高阶列表函数来自列出模块“。这个内联还给匿名函数命名“lists ^ foldl / 2”,而不仅仅是“有趣”。
这是一个简单的演示:
defmodule Fold do
@compile :inline_list_funcs
def main do
sum([1, 2, 3])
end
def sum(list) do
:lists.foldl(fn a, b -> raise "foo" end, 0, list)
end
end
Fold.main
使用@compile :inline_list_funcs
,输出为:
** (RuntimeError) foo
fold.exs:9: anonymous fn/2 in Fold.sum/1
fold.exs:9: Fold."-sum/1-lists^foldl/2-0-"/3
(elixir) lib/code.ex:363: Code.require_file/2
没有它,输出是:
** (RuntimeError) foo
fold.exs:9: anonymous fn/2 in Fold.sum/1
(stdlib) lists.erl:1263: :lists.foldl/3
(elixir) lib/code.ex:363: Code.require_file/2
使用该属性,我们没有lists
模块的任何堆栈跟踪条目,即使我们明确调用:lists:foldl
。
为什么有多个
/3
?
这似乎是Erlang的副作用,包括命名匿名函数时当前函数的arity。
为什么某些名称
-
带有前缀?
上面解释。
^
是什么意思?
这只是sys_core_fold_lists:call/4
选择的名称。
为什么
2-0-
?
2
来自sys_core_fold_lists:call/4
。 0
是referred to as "count" in Exception.format_mfa/3
,但我不确定这意味着什么。
答案 1 :(得分:0)
它是Enum.reduce
实现中某些“匿名”函数的生成名称。我假设这个函数是内联定义的,并作为参数传递给lists:foldl
,因此得名。 AFAIK这样的名字不是由Elixir产生的,而是由Erlang本身产生的。