2015-03-12 5 views
2

Есть ли способ увидеть охранники функции, не видя исходный код?Erlang/Elixir охранники и arity

Учитывая пример функции (в эликсира):

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

Как один выяснить, что есть охранник разделяй/2 без доступа к исходному коду, и как бы один найти информацию об этом охранником или то, что ожидает этот шаблон для соответствия шаблону?

Я наблюдал за разговором Криса МакКорда (создателя феникс-фрейма Эликсира) от Ruby Conf 2014. Во время разговора Крис описывал охранников, и кто-то спросил, есть ли способ проверить функцию, которая будет показывать охранники функции.

Это вопрос из разговора:

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

Спрашивается вскоре после того, как т = время видео.

+0

Просто интересно - какой прецедент здесь? Не следует ли защищать условия, чтобы вы избегали писать плохой код? Поэтому, если вы нарушите условие охраны, перепишите код. –

+0

Мне тоже было любопытно. Один из вариантов использования, который я могу себе представить, - это охраняемая функция, которая (например) допускает только числа от 1 до 10. Как это знать? Ответ, безусловно, «Посмотрите на документы» или «Посмотрите на исходный код», но я надеялся, что будет такой ответ, как «Просто используйте функцию' '' SomeModule.show_guards/1''' и передайте функции интереса ». –

ответ

5

В настоящее время эту информацию невозможно просмотреть без просмотра источника.

+0

Вы можете посмотреть созданный код BEAM. :-) Просто шутка. – rvirding

+1

Теперь есть способ увидеть охрану и арность функции, не глядя на исходный код. Elixir 1.5 вводит 'Exception.blame/3', который вызывается при определенных ошибках (например,' FunctionClauseError'). 'Exception.blame/3' отображает точно информацию в этом вопросе (и многое другое). Требуется Erlang/OTP 20. Посмотрите здесь: https://elixir-lang.org/blog/2017/07/25/elixir-v1-5-0-released/ –

0

Если в файле луча есть информация об отладке, можно создать библиотеку, которая анализирует ее и получает то, что вам требуется, не заглядывая в исходный код. Вот один пример в Erlang, как вы можете получить атрибуты функции.

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] 

Для примера модуля, названного фактом с 2 функциями, также называемым фактом, вы можете получить вышеупомянутый вывод.

Оговорки в абстрактном коде будут иметь охранники с атомом op. Они также могут быть восстановлены.