【发布时间】:2013-07-10 20:23:29
【问题描述】:
这是一些我认为 Dialyzer 应该能够发现的错误代码:
-module(myapp_thing).
-spec exists(pos_integer()) -> yes | no.
exists(Id) ->
myapp_mnesia:thing_exists(Id).
-module(myapp_mnesia).
thing_exists(Id) ->
Exists = fun() ->
case mnesia:read({thing, Id}) of
[] -> false;
_ -> true
end
end,
mnesia:activity(transaction, Exists).
myapp_thing:exists/1被指定为返回yes | no,但返回类型实际上是true | false(即boolean()),也就是myapp_mnesia:thing_exists/1返回的内容。
但是,在 myapp 上运行 Dialyzer 会通过它而不会发出警告。
如果我将myapp_mnesia:thing_exists/1 更改为只返回true,我会收到适当的警告;同样,如果我添加正确的规范:
-spec session_exists(pos_integer()) -> boolean().
但看起来 Dialyzer 无法查看 mnesia 事务函数 Exists 内部,或者由于某些其他原因无法推断出 thing_exists 的返回类型。
那么,mnesia 事务函数是 Dialyzer 的障碍,还是 Dialyzer 的返回类型推断存在更普遍的障碍?
【问题讨论】:
-
据我所知,
mnesia:activity/2没有-spec类型。添加-spec mnesia:activity(atom(), fun(()->X)) -> X.之类的内容可能会有所帮助(尽管我还没有尝试过)。 -
函数规范中可以有类型变量!?凉爽的! erlang.org/doc/reference_manual/typespec.html#id76207 但是,我宁愿不摆弄 mnesia 源。我在 myapp_mnesia 中键入函数。我想了解更多有关 Dialyzer 推理障碍的信息。