[erlang-questions] Dialyzer "no local return" warning for anonymous functions
Hynek Vychodil
hynek@REDACTED
Thu Dec 16 00:42:41 CET 2010
I'm afraid it is not what you are looking for.
-module(funky).
-export([my_funky_mnesia_test/2, test/2, transaction/1]).
test(A, B) ->
try
?MODULE:transaction((fun my_funky_mnesia_test/2)(A,B))
catch
exit:{aborted, all_valid} -> ok;
exit:{aborted, Error} -> {error, Error}
end.
transaction(T) ->
io:format("Start transaction.~n", []),
T(),
io:format("End transaction.~n", []).
my_funky_mnesia_test(A, B) ->
io:format("Inside Transaction (~p,~p)~n", [A, B]),
mnesia:abort(all_valid).
---8<-------------------->8---
1> c(funky).
{ok,funky}
2> funky:test(foo, bar).
Inside Transaction (foo,bar)
ok
What happen? Execution not even reach calling ?MODULE:transaction/1
because exception is raised when evaluating ?MODULE:transaction/1
parameter. (fun my_funky_mnesia_test/2)(A,B) calls
my_funky_mnesia_test/2 and don't return fun/0 which should be passed
into ?MODULE:transaction/1
Unfortunately correct fun() -> (fun my_funky_mnesia_test/2)(A,B) end
is same as fun() -> my_funky_mnesia_test(A,B) end which obviously
doesn't make Dialyzer happy again. You have to make something like
-spec my_funky_mnesia_test_maker(some_t(), another_t()) -> fun(()->
no_return()).
my_funky_mnesia_test_maker(A,B) ->
fun() -> my_funky_mnesia_test(A,B) end.
On Wed, Dec 15, 2010 at 11:53 PM, Bernard Duggan <bernie@REDACTED> wrote:
> On 15/12/10 20:08, Kostis Sagonas wrote:
>>
>> Bernard Duggan wrote:
>>>
>>> As far as I
>>> know, though, there's no way to -spec an anonymous function, nor is
>>> there any obvious way to make that particular function not anonymous.
>>
>> It's too early in the morning for me, but doesn't the following do it?
>> (Warning: untested -- I also think the parentheses aroung the fun object
>> are not really needed, but perhaps the code is clearer with them)
>>
>> validate(A, B) ->
>> try
>> mnesia:transaction((fun my_funky_mnesia_test/2)(A,B))
>> catch
>> exit:{aborted, all_valid} -> ok;
>> exit:{aborted, Error} -> {error, Error}
>> end.
>>
>> -spec my_funky_mnesia_test(some_t(), another_t()) -> no_return().
>>
>> my_funky_mnesia_test(A, B) ->
>> some_test_db_operations(A, B),
>> mnesia:abort(all_valid).
>
> Indeed that does do it - thank you very much. It had never occurred to me
> that you could call fun objects directly like that. Of course in hindsight
> it's obvious, but then hindsight usually is :)
>
> Cheers,
>
> Beranrd
>
> ________________________________________________________________
> erlang-questions (at) erlang.org mailing list.
> See http://www.erlang.org/faq.html
> To unsubscribe; mailto:erlang-questions-unsubscribe@REDACTED
>
>
--
--Hynek (Pichi) Vychodil
Analyze your data in minutes. Share your insights instantly. Thrill
your boss. Be a data hero!
Try GoodData now for free: www.gooddata.com
More information about the erlang-questions
mailing list