How to specify(force) the Data Type of fields in records.

Papa Tana papa.tana101@REDACTED
Tue Jul 7 22:25:41 CEST 2020


Ok. Running dialyzer on my module yields the following (sure, it
violates on purpose the declared type of field name):

Eshell V11.0  (abort with ^G)
1> c(mym).
{ok,mym}

2> mym:start().
{true,{computer,blaster,"55.0",<<0>>,undefined}}
3>

$ dialyzer mym.erl
  Checking whether the PLT c:/Users/Lova/.dialyzer_plt is up-to-date... yes
  Proceeding with analysis...
mym.erl:15: Function start/0 has no local return
mym.erl:16: Record construction
          #computer{name :: 'blaster',
                    price :: [46 | 48 | 53, ...],
                    address :: <<_:8>>} violates the declared type of
field name ::
          string() and price ::
          atom() and address ::
          {byte(), byte(), byte(), byte()} |
          {char(),
           char(),
           char(),
           char(),
           char(),
           char(),
           char(),
           char()}
 done in 0m0.17s
done (warnings were emitted)

Regards,

2020-07-07 23:02 UTC+03:00, Hugo Mills <hugo@REDACTED>:
> On Tue, Jul 07, 2020 at 10:21:42PM +0300, Papa Tana wrote:
>> Hi All,
>>
>> I would like to create a Record, with Strict Data Type as Input:
>> 		- name must be a string
>> 		- price must be an atom
>> 		- address must be an Ip address
>> 		- rest can be anything
>> 		
>> Here is my code:
>>
>> -module(mym).
>>
>> -type personal_name() :: string().
>> -type personal_price() :: atom().
>> -type personal_address() :: inet:ip_address().
>>
>> -record(computer, {
>> 					name :: personal_name(),
>> 					price :: personal_price(),
>> 					address :: personal_address(),
>> 					rest }).
>>
>> -export([start/0]).
>>
>> start()->
>> 	C = #computer{
>> 					name= blaster,
>> 					price= "55.0",
>> 					address= <<0:8>> },
>> 					
>> 	{is_record(C, computer),C}.
>> 	
>> When I run it:
>>
>> 1> mym:start().
>> {true,{computer,blaster,"55.0",<<0>>,undefined}}
>> 2>
>>
>> undefined is normal, but:
>>     * name= blaster, %% I put an atom, I want it to be accepted only if a
>> string
>>     * price= "55.0", %% should accept only atom
>>     * address= <<0:8>>, %% shoul accept only ip_address, not binary
>>
>> Could you please tell me how to specify(force) the Data Type of these
>> input value?
>>
>> Thanks,
>
>    The type annotations you're using here aren't actually looked at or
> checked by the compiler. Instead, there's a separate tool called
> "dialyzer", which can be used to verify expected types of functions,
> and whether those functions might be successful.
>
>    If you're dealing with external input, validate that input (by, for
> example, guard expressions such as the is_* functions from the erlang
> module) as soon as possible. If you do that, dialyzer can determine
> that subsequent uses of those variables are particular types, and can
> do a good job of verifying that the rest of your code is type-safe.
>
>    Hugo.
>
>
> --
> Hugo Mills             | Be pure.
> hugo@REDACTED carfax.org.uk | Be vigilant.
> http://carfax.org.uk/  | Behave.
> PGP: E2AB1DE4          |                                   Torquemada,
> Nemesis
>


More information about the erlang-questions mailing list