[erlang-questions] Trouble with init/1 spec
Kostis Sagonas
kostis@REDACTED
Wed Mar 24 17:40:39 CET 2010
Jay Nelson wrote:
>
> On Mar 24, 2010, at 9:00 AM, Kostis Sagonas wrote:
>
>> The type
>>
>> [string() | non_neg_integer()]
>>
>> constrains the input argument better than list()
>>
>>> Declaring it as list(any()) means the fields on the record have to
>>> all be declared any(). As long as my port field is declared
>>> non_neg_integer() in the record definition, I can't get past the
>>> dialyzer warning.
>>
>> Huh? Are you sure? The record fields can be declared whatever type
>> you want. I am not sure to what dialyzer warning you are referring
>> to, but perhaps we can take this off list.
>
> I didn't state that too clearly. The list(any()) caused dialyzer to
> deduce that the record assignment was creating an any() value in a
> field, therefore my record declaration each field needs to be any()
> rather than string() or non_neg_integer().
>
> If I make the arglist [string() | non_neg_integer()], then I have to
> declare all my string() fields in the record to be of the same type
> because of the record constructor assignments which is really misleading
> to label a server name or user name as a non_neg_integer() and propagate
> that to any functions that access the field.
>
> Right now the only way to get around it easily is to make my port field
> a string() and do the list_to_integer/1 conversion every time I access
> it. That way all the fields in the init/1 list just happen to become
> string().
I really have no idea what you are referring to... Have you actually
tried the above (if so, some example code showing the dialyzer warning
will help me see what the trouble is), or you are just assuming that you
will have to do them?
For example, I tried the following (a simplified version of your code):
---------------------------------------------------------------
-module(jay).
-export([init/1]).
-record(twfsm_state, {server = "abc" :: string(),
port = 42 :: integer()}).
-spec init(list()) -> {ok, #twfsm_state{}}.
init([Server, Port]) ->
{ok, #twfsm_state{server=Server, port=Port}}.
---------------------------------------------------------------
run dialyzer as follows:
% dialyzer jay.erl
Checking whether the PLT /home/kostis/.dialyzer_plt is up-to-date... yes
Proceeding with analysis... done in 0m4.38s
done (passed successfully)
and as you can see I got no warnings from dialyzer.
I've even changed the spec to:
-spec init([string() | integer()]) -> {ok, #twfsm_state{}}.
and still got no warnings from dialyzer.
I really want to understand this. What exactly is that you claim you
cannot really do without getting a dialyzer warning?
Kostis
More information about the erlang-questions
mailing list