我来自Java和Ruby背景,我想知道Erlang中是否有任何“method_missing”等价物。我查看了文档,我能看到的最接近的是使用erl_eval和erl_parse,但我想知道是否有其他方法?
答案 0 :(得分:18)
当您尝试调用未定义的函数时,会调用'error_handler'模块。
process_flag(error_handler, Module).
模块需要导出undefined_function/3
和undefined_lambda/3
。您可以在标准处理程序模块error_handler
中看到它应该如何实现。
您需要小心自己error_handler
不要破坏标准代码加载系统。 Erlang通常会尝试从未定义的函数错误加载模块,并在放弃并发出错误信号之前重新运行该函数。您通常希望首先尝试标准的error_handler,如果失败则回退到新的行为。
答案 1 :(得分:3)
如果您正在进行“防御性编码”,可以致电Module:module_info(exports)
查看您要拨打的功能是否已导出。
答案 2 :(得分:3)
error_handler
,它确实支持一个很好的回调例程,通知模块被调用,试图调用一个未定义的函数,这似乎非常方便。
https://github.com/erlang/otp/blob/maint/lib/kernel/src/error_handler.erl#L139
因此,如果您在模块中添加它:
'$handle_undefined_function'(Func, Args) ->
io:format("Called undefined function '~p' with args ~p.~n", [Func, Args]).
每当调用该模块中的未定义函数时,它都会打印出一条消息。
答案 3 :(得分:1)
Erlang的函数不是方法,通常尝试调用未定义的函数被认为是错误。
如果您尝试在同一模块中调用不存在的函数,编译器将生成错误。尝试在另一个模块中调用函数将在运行时生成错误undef
错误。您希望如何处理此类错误取决于您的应用程序。
答案 4 :(得分:0)
我在调用端使用类似模式,模块可能提供日志级别分类功能(可能返回无效结果)。我是这样做的:
-spec categorize(atom(), integer()) -> log_classification().
categorize(Module, Code) ->
case catch(Module:ns_log_cat(Code)) of
info -> info;
warn -> warn;
crit -> crit;
_ -> info % Anything unknown is info (this includes {'EXIT', Reason})
end.
由于没有方法(一般来说,你当然可以创建一个OO行为并用消息实现它然后有method_missing
,被调用者不知道我尝试了什么,所以它不能解释它。