Erlang和method_missing

时间:2010-01-14 18:12:30

标签: erlang method-missing

我来自Java和Ruby背景,我想知道Erlang中是否有任何“method_missing”等价物。我查看了文档,我能看到的最接近的是使用erl_eval和erl_parse,但我想知道是否有其他方法?

5 个答案:

答案 0 :(得分:18)

当您尝试调用未定义的函数时,会调用'error_handler'模块。

process_flag(error_handler, Module).

模块需要导出undefined_function/3undefined_lambda/3。您可以在标准处理程序模块error_handler中看到它应该如何实现。

您需要小心自己error_handler不要破坏标准代码加载系统。 Erlang通常会尝试从未定义的函数错误加载模块,并在放弃并发出错误信号之前重新运行该函数。您通常希望首先尝试标准的error_handler,如果失败则回退到新的行为。

答案 1 :(得分:3)

如果您正在进行“防御性编码”,可以致电Module:module_info(exports)查看您要拨打的功能是否已导出。

答案 2 :(得分:3)

archaelus指出了一个很好的方向,但如果你不想干涉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,被调用者不知道我尝试了什么,所以它不能解释它。