2017-09-30 1 views
2

Voici mes codes:peut ne pas correspondre à la bonne fonction

-record(user,{id,name,group,age}). 

adult_section(U=#user{}) when U#user.age >=18 -> "allowed"; 

adult_section(_) -> "no permission". 

il peut être travaillé avec:

>records_new:adult_section(#user{id=1,name='Ray',group=admin,age=10}). 
    output: "no permission" 

mais quand j'essaie ceci:

> records_new:adult_section(#user{}). 
    "allowed" 

Je n » t donner l'âge de l'utilisateur dans le deuxième ordre, pourquoi il peut être travaillé, pourquoi ne pas "no permission".

+3

Vous devez toujours spécifier les valeurs par défaut * pour les enregistrements. Toujours. 'undefined' est une valeur qui causera presque toujours des résultats inattendus si vous courez juste et pensez que Erlang est comme Python ou Javascript (ou peu importe). Les typespecs et les valeurs par défaut saines sont critiques pour un code sans surprise - Erlang rend réellement ceci visuellement attrayant * et * très lisible. Cela dit, la réponse de @ Dogbert est exactement correcte: les atomes se comparent à des valeurs plus élevées que tous les entiers, donc 'non défini> = 18' est toujours' vrai'. – zxq9

Répondre

7

Depuis votre dossier n'a pas de valeur par défaut pour age, si vous créez l'enregistrement sans spécifier une valeur pour age, sa valeur par défaut à l'atome undefined.

1> #user{}. 
#user{id = undefined,name = undefined,group = undefined, 
     age = undefined} 

En Erlang, les atomes se comparent plus que des nombres entiers:

2> undefined > 18. 
true 
3> foo > 100000000. 
true 

Si vous spécifiez une valeur par défaut de l'âge d'être par exemple 0, votre fonction fonctionne comme prévu:

-record(user,{id,name,group,age = 0}). 
1> #user{}. 
#user{id = undefined,name = undefined,group = undefined, 
     age = 0} 
2> a:adult_section(#user{}). 
"no permission" 
1

Vous devriez regarder dans Dogbert answer. Son explication est sur place.

Je voudrais seulement ajouter que vous pourriez vous protéger contre une telle injection de «mauvaises données» en élargissant votre garde.

adult_section(U=#user{}) when 
    is_integer(U#user.age) andalso 
    U#user.age >=18 -> 
    "allowed";