开发者

Erlang and method_missing

I come from a Java and Ruby back开发者_如何学编程ground and I was wondering if there is any equivalent of "method_missing" in Erlang. I have looked at the documentation and the closest I can see is the use of erl_eval and erl_parse, but I wanted to know if there is any other way?


There is the 'error_handler' module which is called when you attempt to call an undefined function.

process_flag(error_handler, Module).

The module needs to export undefined_function/3 and undefined_lambda/3. You can see how this should be implemented in the standard handler module, error_handler.

You need to be careful in your own error_handler not to break the standard code loading system. Erlang usually tries to load the module from an undefined function error and re-run the function before giving up and signalling an error. You usually want to try the standard error_handler first and fall back to your new behaviour if that fails.


archaelus pointed in a good direction, but if you prefer not to meddle with the error_handler, it does support a nice callback routine notifying the module being called that there was an attempt to call an undefined function, which seems quite handy.

https://github.com/erlang/otp/blob/maint/lib/kernel/src/error_handler.erl#L139

So if you add this in a module:

'$handle_undefined_function'(Func, Args) ->
     io:format("Called undefined function '~p' with args ~p.~n", [Func, Args]).

It'll print out a message whenever a call is made to a undefined function in that module.


If you are into "defensive coding", you can call Module:module_info(exports) to see if the function you're about to call is exported or not.


Erlang has functions not methods and generally trying to call an undefined function is considered to be an error.

The compiler generates an error if you try to call a non-existent function within the same module. Trying to call a function in another module will generate an error at runtime, the undef error. How you wish to handle such an error depends on your application.


I'm using a similar pattern on the calling side where a module may supply a log level classification function (which may return invalid results). I do it like this:

-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.

Since there isn't a method (in general, you could certainly create an OO behavior and implement it with messages and then have method_missing, the callee doesn't know I attempted anything, so it can't interpret it.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜