[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