Accessing variables in Main within a Module using RCall

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

Thanks @genkuroki!