I'm using Erlang R16B03.
This code:
list_dir(Directory, Retries) when is_integer(Retries), Retries > 0 ->
Port = get_efile_port(),
try erlang:port_info(Port) of
Result ->
error_logger:info_msg("list_dir - erlang:port_info(~p) -> ~p ", [Port,Result])
catch
_:Reason ->
error_logger:info_msg("list_dir - erlang:port_info(~p) -> {error, ~p }",[Port,Reason])
end,
case prim_file:list_dir(Port, Directory) of
{error, einval} ->
error_logger:info_msg(" list_dir - port : ~p , directory : ~p", [Port, Directory]),
clear_efile_port(),
list_dir(Directory, Retries-1);
Result ->
Result
end.
Generates the following compiler exception:
/basho/riak/deps/bitcask/src/bitcask_fileops.erl:855: variable 'Result' unsafe in 'try' (line 843)
ERROR: compile failed while processing /basho/riak/deps/bitcask: rebar_abort
make: *** [compile] Error 1
But if I rename the first use of the variable name Result
to Res
, it compiles fine, e.g:
list_dir(Directory, Retries) when is_integer(Retries), Retries > 0 ->
Port = get_efile_port(),
try erlang:port_info(Port) of
Res ->
error_logger:info_msg("list_dir - erlang:port_info(~p) -> ~p ", [Port,Res])
catch
_:Reason ->
error_logger:info_msg("list_dir - erlang:port_info(~p) -> {error, ~p }",[Port,Reason])
end,
case prim_file:list_dir(Port, Directory) of
{error, einval} ->
error_logger:info_msg(" list_dir - port : ~p , directory : ~p", [Port, Directory]),
clear_efile_port(),
list_dir(Directory, Retries-1);
Result ->
Result
end.
As far as I can see the variables are within two different scopes (try/catch and case).
Is this a compiler bug or have I failed to understand the Erlang syntax correctly?
This is not a compiler bug. The problem is that in the first example, you use Result
in two places: first in the try
, and then again in the case
. These are not two different scopes, but the same scope. The compiler is complaining because if there's no exception raised in the try
, Result
will be bound to the result of the erlang:port_info(Port)
call, but if that call raises an exception, Result
will not be bound. This means its use within the case
will be ambiguous, since in the second case
clause it would be matched if it's already bound, or bound to the result of prim_file:list_dir(Port, Directory)
if it's not already bound.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With