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