Rui MA
Rui MA

Reputation: 31

Can't match the right function

Here's my codes:

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

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

adult_section(_)    ->  "no permission".

it can be worked with:

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

but when I try this:

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

I didn't give the user's age in the second order, why it can be worked, why is not "no permission".

Upvotes: 1

Views: 48

Answers (2)

mpm
mpm

Reputation: 3584

You should look into Dogbert answer. His explanation is spot-on.

I would like to only add that you could protect yourself from such "bad-data" injection by expanding your guard.

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

Upvotes: 1

Dogbert
Dogbert

Reputation: 222408

Since your record does not have a default value for age, if you create the record without specifying a value for age, it defaults to the atom undefined.

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

In Erlang, atoms compare greater than integers:

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

If you specify a default value of age to be e.g. 0, your function works as you expect:

-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"

Upvotes: 5

Related Questions