[erlang-questions] Record typing for dialyzer

Bernard Duggan bernie@REDACTED
Wed Nov 25 01:51:41 CET 2009


That was another other option I toyed with - I ended up coming down on
the side of keeping the "code" as un-hacked as possible and just messing
with the headers and auto-generated stuff.  My reasoning being that I
didn't want others in the team to have to re-solve the problem every
time they wanted to use a select() statement.  Not that I'm saying it's
not a perfectly valid solution, just explaining why I didn't choose it :)

Cheers,

B

Paul Mineiro wrote:
> I had the same problem.
>
> I ended up keeping the type signature in the declaration strict, and using
> setelement/3 to construct the type-violating version of the record that I
> pass to mnesia:select/2.
>
> -- p
>
> On Wed, 25 Nov 2009, Bernard Duggan wrote:
>
>   
>> Hi list,
>>     We have a lot of auto-generated record types that we use to allow
>> our (newer, awesomer) erlang/mnesia code to interact with our (older,
>> less awesome, but we're stuck with it for now) C++/mysql code.  It
>> recently occurred to me that it would be a simple matter to add type
>> specifiers to the records to give dialyzer (which we love to death) some
>> extra info to work with.  And for the most part it was.  So we now have
>> nice auto-generated records of the form:
>>
>> -record( person{
>>     id :: integer(),
>>     name :: string(),
>>     is_awesome :: boolean()
>> }).
>>
>> which is great (and already helped us find several bugs - have I
>> mentioned we love dialyzer?).  We struck a problem, however, when we
>> used one of our records in a select statement thus:
>>
>> Match = #person{name="Bernie", id='$1', _='_'},
>> mnesia:select(person, [{Match, [], [{{'$1'}}]}]),
>>
>> At this point, dialyzer quite correctly points out that '$1' isn't an
>> integer and '_' isn't a boolean and so we've got no business assigning
>> them to fields typed as such.
>>
>> My solution, then was to add an extra type definition:
>>
>> -type search_spec() :: '_' | '$1' | '$2' | '$3' | '$4' | '$5' | '$6' |
>> '$7' | '$8' | '$9'.
>>
>> and change all the record definitions to something like:
>>
>> -record( person{
>>     id :: integer() | search_spec(),
>>     name :: string() | search_spec(),
>>     is_awesome :: boolean() | search_spec()
>> }).
>>
>> Now this solves the problem, but it really looks ugly and seems like
>> kind of a hack and I can't help but feel like there must be some more
>> elegant solution.  But I don't know what it is :)  Any input (even if
>> it's only "nope, there's no better way to do it") would be greatly
>> appreciated.
>>
>> Cheers,
>>
>> Bernard
>>
>> ________________________________________________________________
>> erlang-questions mailing list. See http://www.erlang.org/faq.html
>> erlang-questions (at) erlang.org
>>
>>
>>     
>
>
> ________________________________________________________________
> erlang-questions mailing list. See http://www.erlang.org/faq.html
> erlang-questions (at) erlang.org
>
>   



More information about the erlang-questions mailing list