I would like to access variables declared in Main from within a module but they’re not in scope and I wonder how this can be achieved.
using RCall
x = 1
f(var::String) = eval(Meta.parse("@rput ("*var*")"))
module M1
using RCall
import RCall: @rput
f(var::String) = eval(Meta.parse("@rput ("*var*")"))
end
julia> f("x")
1
julia> M1.f("x")
ERROR: UndefVarError: x not defined
julia> M1.f("Main.x")
ERROR: LoadError: Incorrect usage of @rput
You can use fully qualified variable name
julia> M1.f("Main.x")
1
Alternatively you can import names into module
module M1
using Main: x
f(var::String) = eval(Meta.parse("println("*var*")"))
end
julia> M1.f("x")
1
Hi @Skoffer
Thank you very much for your answer, unfortunately I simplified the problem too much.
I am using @rput from the RCall package and @rput Main.x returns and error. I just updated the original post with an slightly less simplified example.
It is rather difficult to understand eval functions. Each module has its own eval(x), which evaluates expressions in that module (= name space).
using RCall
x = 1
f(var::String) = eval(:(@rput($(Symbol(var)))))
module M2
using RCall
x = 2
f(var::String) = eval(:(@rput($(Symbol(var)))))
g(var::String) = Main.eval(:(@rput($(Symbol(var)))))
g(m::Module, var::String) = Core.eval(m, :(@rput($(Symbol(var)))))
end
julia> M2.f("x")
2
julia> R"x"
RObject{IntSxp}
[1] 2
julia> M2.g("x")
1
julia> R"x"
RObject{IntSxp}
[1] 1
julia> M2.g(M2, "x") # equivalent to M2.f("x")
2
julia> R"x"
RObject{IntSxp}
[1] 2
1 Like