[erlang-questions] Help - Can I stop this warning?

G Bulmer <>
Sat Sep 22 19:57:50 CEST 2007


Hmm, I'm still not getting it.
I accept that a fun is overkill in this situation, but I was trying  
to get the tactic clear.
Unfortunately I seem to have created a deeper problem.

This is wrong:
-define(FUN1, (fun() -> {_,{_,F,_}} = process_info(self 
(),current_function), F end)()).
because the function name is based on the name *within* the scope of  
the fun,
so it returns ugly things like '-test0/0-fun-0-'

So, this is what I would expect to be correct:
-define(FUN, ((fun(X) -> {_,{_,F,_}} = X, F end)
                                       (process_info(self 
(),current_function))) ).
-define(IOFUN(), io:format("~p: ", [?FUN])).

test0() ->
     ?IOFUN(), io:format("explode if F is bound~n"),
     F = wibble,
     io:format("clearly, everything is fine with F, and wibble ==  
~p~n", [F]),
     ?IOFUN(), io:format("Finished.~n").

Unfortunately, this fails:
11> scriptbug:test0().
test0: explode if F is bound
clearly, everything is fine with F, and wibble == wibble

=ERROR REPORT==== 22-Sep-2007::18:35:21 ===
Error in process <0.69.0> on node '' with exit  
value: {{badmatch,{current_function,{scriptbug,test0,0}}}, 
[{scriptbug,'-test0/0-fun-1-',1},{erl_eval,do_apply,5},{shell,exprs, 
6},{shell,eval_loop,3}]}

** exited: {{badmatch,{current_function,{scriptbug,test0,0}}},
             [{scriptbug,'-test0/0-fun-1-',1},
              {erl_eval,do_apply,5},
              {shell,exprs,6},
              {shell,eval_loop,3}]} **

Now just to make things interesting, I remove F in test0()
test0() ->
     ?IOFUN(), io:format("explode if F is bound~n"),
     % F = wibble,
     io:format("clearly, everything is fine with F, and wibble ==  
~p~n", [wibble]),
     ?IOFUN(), io:format("Finished.~n").

The result is now correct:
13> scriptbug:test0().
test0: explode if F is bound
clearly, everything is fine with F, and wibble == wibble
test0: Finished.
ok

I can't see why this fails with F = wibble in the first version of  
test0(), when that should be the only match operation on F in that  
scope.
Worse, I can't see why it fails in the first version of test0(), but  
at the second macro expansion; I would expect the failure at 'F =  
wibble' if F is in scope from the first ?IOFUN()!
Finally, if there is some cleverness going on inside the ?IOFUN()  
macro expansion, I would expect F to have the same value in each case  
anyway.

Any hints or techniques that I could use to get better information so  
that I can debug these things in future?

Garry

> Tim Bates wrote:
>> G Bulmer wrote:
>>> I have been playing with this macro to print the current  
>>> functions name:
>>>
>>> -define(IOFUN(), io:format("~s: ", [case process_info(self
>>> (),current_function) of {_,{_,F,_}} ->F end])).
>>>
>>> Unfortunately, I get this irritating warning on *every* function, on
>>> the first use of ?IOFUN():
>>> ./script.erl:34: Warning: variable 'F' exported from 'case' (line  
>>> 31)
>>> ...
>>>
>>> Can someone suggest how I get rid of it?
>>
>> -define(IOFUN(), io:format("~s: ", [element(2, element(2,
>> process_info(self(),current_function)))])).
>
> That's a good solution in this case, but for the general case when you
> want a macro to do something more complicated, and avoid contaminating
> the environment, use a fun-expression to simulate local variables:
>
> -define(my_macro, ((fun()-> ... end)())).
>
> Variables defined in ... are not exported outside the fun.
>
>     /Richard




More information about the erlang-questions mailing list