Erlang/Elixir guards and arity

572 Views Asked by At

Is there a way to see a function's guards without seeing the source code?

Given an example function (in Elixir):

def divide(x, y) when y != 0 do
  x / y
end

How would one figure out that there is a guard on divide/2 without access to the source code, and how would one find info about that guard or what that guard expects for a pattern match?

I was watching a talk by Chris McCord (creator of Elixir's Phoenix Framework) from Ruby Conf 2014. During the talk Chris was describing guards and someone asked if there was a way to inspect a function that would show the function's guards.

This is the question from the talk:

https://www.youtube.com/watch?v=5kYmOyJjGDM&t=5188

The question is asked shortly after the video's t= time.

2

There are 2 best solutions below

2
José Valim On BEST ANSWER

Currently it is not possible to introspect this information without looking at the source.

0
Vinod On

If there is debug info in the beam file a library can be created that parses it and get you what you require without looking into source code. Here is one example in Erlang how you can get the arities of a function.

1> GetArities = 
  fun(Module, FunName) ->
    {ok,{_,[{abstract_code,{_,AC}}]}} = beam_lib:chunks(Module,[abstract_code]),
    lists:foldl(
      fun({function, _Line, Fun, Arity, _Clauses}, FunArities) when Fun == FunName ->
            [Arity | FunArities];
          (_, FunArities) ->
            FunArities
      end, [], AC)
  end.

2> GetArities(fact,fact).
[1,0]

For a sample module named fact with 2 functions also named fact, you can get the above output.

Clauses in abstract code will have guards with atom op. Those can also be retrieved.