Erlang often uses :undefined
instead of :nil
(and by often, I mean I haven’t really seen an erlang source that uses :nil
). Does anyone have any tips or pointers for avoiding erroneously matching :nil
when :undefined
should have been matched? Does dialyzer help with this?
Dialyzer can help to see those errors before hand, but only if it is configured correctly.
Personally I think, that carefully studying the described API and return values and code according to those described API is much more important than relying on external tools. If you want to avoid that problem for a certain function once and for all, just write a wrapper like this:
def f(a, b, c) do
case :erlang_module.f(b, c, a) do
:undefined -> nil
result -> result
end
end
Testing can help to find those pretty good as well.
Basically this. It may be “inconvenient” but the documentation is upfront about the types - including what is returned. Example: :ets.info/1
info(Tab) -> InfoList | undefined
Types
Tab = tab()`
InfoList = [InfoTuple]
InfoTuple =
{compressed, boolean()} |
{heir, pid() | none} |
{keypos, integer() >= 1} |
{memory, integer() >= 0} |
{name, atom()} |
{named_table, boolean()} |
{node, node()} |
{owner, pid()} |
{protection, access()} |
{size, integer() >= 0} |
{type, type()} |
{write_concurrency, boolean()} |
{read_concurrency, boolean()}
Returns information about table Tab as a list of tuples. If Tab has the correct type for a table identifier, but does not refer to an existing ETS table,
undefined
is returned. If Tab is not of the correct type, a badarg exception is raised.
No, Erlang does not use :nil
at all. Seeing everything always has a value we went for not having anything which could be interpreted as not having a value. I would interpret undefined
as meaning the thing you are try to look at as not being defined. As for example the :ets.info/1
call where it means the table is not defined or in :erlang.whereis/1
where it means that the registered name is not defined.