2012-06-24 28 views
7

me encontré con este código en la web:¿Puedo hacer mis propios guardias en Erlang?

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. 

Su es el Guard I alwais soñado fuera, en la que se comprueba si una entrada es una cadena - cómo cada vez, no estoy autorizado para utilizarla en Erlang, ¿por qué es esto? Y hay un trabajo alrededor?

Me gustaría ser capaz de escribir cosas como:

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

o incluso mejor usarlo en los mensajes.

+4

Sin ánimo de ofender, una mejor forma de probar cadenas de caracteres sería con los métodos: 'io_lib: printable_list/1' y' io_lib: printable_unicode_list/1' utilizados en combinación. –

+0

Ver también [esto] (http://stackoverflow.com/questions/10861347/why-comparing-function-results-is-an-illegal-guard-exception-in-erlang), [this] (http: // stackoverflow.com/questions/6505213/is-there-a-way-to-use-local-function-in-guard), [this] (http://stackoverflow.com/questions/6927632/checking-for-membership -in-an-erlang-guard), [esto] (http: // stackoverflow.com/questions/2241340/unable-to-use-function-call-in-function-guard) y [this] (http://stackoverflow.com/questions/7474894/use-of-function-in-guard-not -allowed-suggestions-for-alternate-implementation-w) pregunta. – legoscia

Respuesta

9

No tiene permitido utilizar las funciones definidas por el usuario en las protecciones. Es porque las funciones en las protecciones deben estar libres de efectos secundarios (como usar io:format en sus funciones). En los guardias, que se limitan a lo siguiente:

  • BIFs utilizados para ensayos de tipo (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),
  • operadores booleanos (not, and, or, andalso, orelse, ,, ;),
  • operadores relacionales (>, >=, <, =<, =:=, ==, =/=, /=),
  • operadores aritméticos (+, -, *, div, rem),
  • operadores bit a bit (band, bor, bxor, bnot, bsl, bsr),
  • otros BIFs tha t están libres de efectos secundarios (abs/1, element/2, hd/1, length/1, node/1,2, round/1, size/1, tl/1, trunc/1, self/0)
+4

Hmm, parecería que buscar efectos secundarios sería un truco bastante fácil de análisis estático ... –

+5

@MartinKristiansen En realidad, no es posible, ya que cualquier código en los módulos puede cambiarse o reemplazarse en tiempo de ejecución. –

+0

@alexeyRomanov: Tiene toda la razón, pero tal vez haga una restricción para usar BIF y solo funciones dentro del módulo actual :-) –

5

Otra razón para no permitir que las funciones definidas por el usuario en guardias es que los errores se manejan de forma diferente en guardias que en funciones "normales". En un protector, un error hace no generar una excepción, solo hace que el protector falle.

Los protectores no son realmente expresiones pero prueban.

Cuestiones relacionadas