Thanh Nguyen
Thanh Nguyen

Reputation: 83

eval could not access variable in function scope

In the MnWE (Minimal not Working Example) below, when I called test(2), I got the error:

ERROR: UndefVarError: var2 not defined in test at ./none:6

How to solve this situation without using global variable var1 and var2. In my real situation, var1 and var2 are two lengthy matrices and needed only once to determine a variable s1. Using them as global variables seems ugly (and ineffective), doesn't it?

Thank you in advance for your help.

function test(arg)
var1=10
var2=100
s="var$arg"
s=symbol(s)
@eval($s)
end

Upvotes: 0

Views: 119

Answers (1)

Bogumił Kamiński
Bogumił Kamiński

Reputation: 69949

eval always evaluates expression in global scope of the current module, thus variables defined inside a function are not in this scope.

Personally I would use a tuple, a vector or a dictionary in such a case as you present. For instance here is the code using Dict:

function test(arg)
    var1=10
    var2=100
    d = Dict(1=>var1, 2=>var2)
    d[arg]
end

And here with a Tuple (and a bit more terse):

test(arg) = (10, 100)[arg]

If var1 or var2 were expensive to create then you can use the following pattern:

function test(arg)
    arg == 1 && return rand(10^7)
    arg == 2 && return rand(10^6)
    throw(ArgumentError("wrong value of arg ($arg)"))
end

in which case only the code that is relevant gets executed. You can achieve the same effect using the above two methods if you wrap generation of var1 and var2 in a function, e.g.

var1() = rand(10^7)
var2() = rand(10^6)
test(arg) = (var1, var2)[arg]()

Upvotes: 3

Related Questions