2012-06-24 3 views
7

я наткнулся на этот код в сети:Могу ли я сделать свою собственную гвардию в Эрланге?

is_char(Ch) ->   
    if Ch < 0 -> false; 
     Ch > 255 -> false; 
     true -> true  
    end. 

is_string(Str) ->    
    case is_list(Str) of   
    false -> false;   
    true -> lists:all(is_char, Str) 
    end. 

Его является охрана Я alwais снилось прочь, в том, что он проверяет, если входной строки - как всегда, я не разрешается использовать в erlang, почему это? И есть ли работа вокруг?

Я хотел бы иметь возможность писать такие вещи, как:

Fun(Str) when is_string(Str) -> Str; 
Fun(Int) when is_integer(Int) -> io:format("~w", [Int]). 

или даже лучше использовать его в сообщениях.

+4

Не обижайтесь, но лучшим способом тестирования для строк были бы методы: 'io_lib: printable_list/1' и' io_lib: printable_unicode_list/1', используемые в комбинации. –

+0

См. Также [это] (http://stackoverflow.com/questions/10861347/why-comparing-function-results-is-an-illegal-guard-exception-in-erlang), [это] (http: // stackoverflow.com/questions/6505213/is-there-a-way-to-use-local-function-in-guard), [это] (http://stackoverflow.com/questions/6927632/checking-for-membership -in-an-erlang-guard), [это] (http: // stackoverflow.com/questions/2241340/неспособный к использованию-функция-вызов-в-функции-защита) и [это] (http://stackoverflow.com/questions/7474894/use-of-function-in-guard-not -allowed-ideas-for-alternate-implementation-w). – legoscia

ответ

9

Вам не разрешено использовать определенные пользователем функции в защитных ограждениях. Это связано с тем, что функции в охранниках должны быть свободны от побочных эффектов (например, с помощью io:format в ваших функциях). В охранниках, вы ограничены следующее:

  • BIFS, используемый для испытаний типа (is_atom, is_constant, is_float, is_integer, is_list, is_number, is_pid, is_port, is_reference, is_tuple, is_binary, is_function, is_record),
  • логические операторы (not, and, or, andalso, orelse, ,, ;),
  • реляционные операторы (>, >=, <, =<, =:=, ==, =/=, /=),
  • арифметические операторы (+, -, *, div, rem),
  • битовые операции (band, bor, bxor, bnot, bsl, bsr),
  • другие BIFs tha т свободны от побочных эффектов (abs/1, element/2, hd/1, length/1, node/1,2, round/1, size/1, tl/1, trunc/1, self/0)
+4

Хм, казалось бы, проверка на побочные эффекты была бы довольно простой трюк статического аналога ... –

+5

@MartinKristiansen Не совсем, потому что любой код в модулях можно изменить или заменить во время выполнения. –

+0

@alexeyRomanov: Вы абсолютно правы, но, возможно, затем сделаете ограничение на использование BIF и только функций внутри текущего модуля :-) –

5

Еще одна причина, не позволяя определенные пользователем функции в охранниками является то, что ошибки обрабатываются по-разному в чем в «нормальных» функциях. В защитнике ошибка не генерирует исключение, это только приводит к сбою самого охранника.

Охранники на самом деле не являются выражениями, но тестов.

Смежные вопросы