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