[erlang-questions] Improve $handle_undefined_function

Loïc Hoguin essen@REDACTED
Tue Jan 22 00:24:12 CET 2013


On 01/22/2013 12:15 AM, Evan Miller wrote:
> On Mon, Jan 21, 2013 at 12:04 PM, Loïc Hoguin <essen@REDACTED
> <mailto:essen@REDACTED>> wrote:
>
>     Hello,
>
>     Just recently the $handle_undefined_function feature was introduced.
>     It is a way to override error_handler mechanisms when a function
>     isn't found, and works per module for all processes, instead of just
>     one.
>
>     Regardless of the intent behind this feature, the implementation
>     that was pushed to master is in my opinion, and apparently others,
>     deeply flawed. The main issue is that it pushes the responsability
>     of propagating the right errors directly to the user, and the user
>     must use extra care when writing this handler.
>
>     For example this handler would be incorrect:
>
>     $handle_undefined_function(__monitor, [process, Pid]) ->
>          do_something();
>     $handle_undefined_function(__demonitor, Pid) ->
>          do_something_else();
>     $handle_undefined_function(F, Args) ->
>          error_handler:raise_undef___exception(?MODULE, F, Args).
>
>     Can you see why?[1] If it's not obvious to you, then perhaps this
>     feature needs more work.
>
>     My proposal is to use an attribute to list the functions defined
>     like this, so that error_handler can make the distinction between
>     undef and badarg directly. The above function would then be written
>     like this:
>
>     $handle_undefined_function(__monitor, [process, Pid]) ->
>          do_something();
>     $handle_undefined_function(__demonitor, Pid) ->
>          do_something_else().
>
>     And the issue would be gone.
>
>
> This is a great point. An attribute is one solution. Another would be
> adding another function, e.g.
> $should_handle_undefined_function(FunctionName, Arity), that determines
> at run-time whether to call the handler.
>
> $should_handle_undefined_function(monitor, 2) -> true;
> $should_handle_undefined_function(demonitor, 1) -> true;
> $should_handle_undefined_function(_, _) -> false.
>
> $handle_undefined_function(monitor, [process, Pid]) -> do_something();
> $handle_undefined_function(__demonitor, Pid) -> do_something_else().
>
> What do you think?

A function is dangerous in that it may return a value conditionally 
(using for example the process dictionary, a receive, or anything else) 
and this can heavily mess up the execution. You can still throw an undef 
error yourself anywhere of course, but this one would look legit and 
most confusing. That could lead to some debugging hell sessions. Perhaps 
you do have a need for dynamically managing the list of allowed functions?

On the other hand, if you just return true or false right away, I don't 
see what this has better compared to much shorter to write attributes.

I'm fine with both even though I favor attributes.

>     Adding an attribute isn't hard, whether you generate code or not,
>     and it can be used by tools to figure out what's going on with the
>     module, providing better integration.
>
>     And why not just use -export and still allow -spec anyway? The
>     function is exported, has specs, but is just defined elsewhere. I'm
>     sure there can be a simple solution that fits a lot better the
>     existing toolbase.
>
>     [1] The answer is: if the first argument to 'monitor' is anything
>     other than the atom 'process', then an undef error will be triggered
>     instead of 'badarg'.
>
>     --
>     Loïc Hoguin
>     Erlang Cowboy
>     Nine Nines
>     http://ninenines.eu
>     _________________________________________________
>     erlang-questions mailing list
>     erlang-questions@REDACTED <mailto:erlang-questions@REDACTED>
>     http://erlang.org/mailman/__listinfo/erlang-questions
>     <http://erlang.org/mailman/listinfo/erlang-questions>
>
>
>


-- 
Loïc Hoguin
Erlang Cowboy
Nine Nines
http://ninenines.eu



More information about the erlang-questions mailing list