3

Can anyone enlighten me as to why this bit of code spits back that the X is unsafe in 'try', well I know why, but more so how to fix it.

try X = lists:append(lists:zipwith3(fun(X, Y, Z) -> [X, Y, Z] end, Data1, Data2, Data3)) of
            MP -> X
            catch K -> (X = 0)
            end.
            %MP = [lists:zipwith3(X, Y, Z) || X, Y, Z <-  [Data1, Data2, Data3]],


P = X
Tadmas
  • 6,238
  • 3
  • 39
  • 31
BAR
  • 15,909
  • 27
  • 97
  • 185

2 Answers2

11

The simplest way to fix it is to put the assignment outside of the try-catch:

X =
    try lists:append(lists:zipwith3(fun(X, Y, Z) -> [X, Y, Z] end, Data1, Data2, Data3)) of
        MP -> MP
    catch K -> 0
    end.

As for why this happens, the chapter on expressions in the Erlang reference manual says:

For the try expression variable scoping is limited so that variables bound in the expression are always 'unsafe' outside the expression.

It used to say "This is to be improved", but that was removed in this commit.

legoscia
  • 39,593
  • 22
  • 116
  • 167
1

It is unsafe I believe due to the fact that you do not cover all the exceptions. When you have

catch K -> (X = 0)

I believe it'll only catch thrown exceptions, there are still errors, and exits. IIRC so you will probably need

catch _:K -> (X=0)

or explicitly catch them as

catch 
  error:K -> (X=0);
  exit:K -> (X=0);
  throw:K -> (X=0)

(I'm not 100% that I have the atom names correct, but the idea is still the same)

Kyle d'Oliveira
  • 6,382
  • 1
  • 27
  • 33