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

Papa Tana papa.tana101@REDACTED
Tue Jul 7 22:56:52 CEST 2020


When I put the correct values:

C = #computer{
	name= "blaster",
	price= some_atom,
	address= {192,168,1,82} }

$ dialyzer mym.erl
  Checking whether the PLT c:/Users/Lova/.dialyzer_plt is up-to-date... yes
  Proceeding with analysis... done in 0m0.17s
done (passed successfully)	


I agree that I should use guard expressions such as is_atom, is_*....
but I was only wondering if there was another way to do so during my
record definition in Erlang.

Best Regards,


2020-07-07 23:25 UTC+03:00, Papa Tana <papa.tana101@REDACTED>:
> 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