merch
merch

Reputation: 945

Using eval in Julia to deal with varargs

I have just started using Julia. I am trying to use eval (in Julia) in order to define a set of variables in a function. Let's say I want to set v1 equal to 2:

function fun_test(varargs...)
  v1 = 0;

  if length(varargs) > 0
    j = collect(linspace(1,length(varargs)-1,length(varargs)/2));

    for i in j
      expr_vargs = parse("$(varargs[i]) = $(varargs[i+1]);");
      eval(expr_vargs);
    end
  end

  println(v1)

end

Calling the function as:

fun_test("v1", "2");

It doesn't work, since println returns 0 (the initial value of v1). However, if I run an analogous eval call in the Julia's terminal, then it works.

Could you please clarify why it doesn't work and how to fix it?

Upvotes: 3

Views: 311

Answers (1)

Fengyang Wang
Fengyang Wang

Reputation: 12061

eval runs in toplevel scope, not in function scope. It is not possible to dynamically update bindings in function scope. Without knowing your precise use case, I suspect there is a way to do things without dynamic rebinding. In particular, v1, v2, etc. is probably best made into an array, V.

Nevertheless, if you really must, you can always define v1 as a global variable in a submodule:

module FunTest
v1 = 0
function fun_test(varargs...)

  if length(varargs) > 0
    j = collect(linspace(1,length(varargs)-1,length(varargs)/2));

    for i in j
      @eval $(varargs[i]) = $(varargs[i+1])
    end
  end

  println(v1)

end
export fun_test
end
using .FunTest
fun_test(:v1, 2)  # result: 2

(I have also modified your code to avoid parseing strings, which is best done through expression interpolation.)

Upvotes: 5

Related Questions