How to intercept module variable getting and setting in Julia 1.8 similar to getproperty and setproperty! for structures?

Please help, how to intercept get and set variable of module in Julia 1.8 ?

julia> module M end;

julia> # in julia 1.9 i can do this:
julia> function Base.setproperty!(m::Module, p::Symbol, v)
           println("variable $p changed on $v in module $m")
           return setglobal!(m, p, v)
       end;

julia> # what about julia 1.8 ?

julia> M.x = 1;
variable x changed on 1 in module Main.M

That looks like a XY question, but:

julia> module M 
           x = 2
       end

julia> using .M

julia> M.x
2

julia> M.x = 1
1

julia> M.x
1
1 Like

Could you tell us more about what you are trying to do overall?

julia> module M end;

julia> M.x = 1
ERROR: cannot assign variables in other modules
Stacktrace:
 [1] setproperty!(x::Module, f::Symbol, v::Int64)
   @ Base .\Base.jl:32
 [2] top-level scope
   @ REPL[2]:1

julia> @eval M x = 1
1

julia> M.x
1
1 Like

oh sorry, my english is bad)

i need to override this as getproperty() and setproperty!() for structs

julia> mutable struct Foo
           x::Int
       end

julia> import Base: setproperty!, getproperty

julia> setproperty!(value::Foo, name::Symbol, x) = setfield!(value, name, x*2)
setproperty! (generic function with 12 methods)

julia> foo = Foo(0)
Foo(0)

julia> foo.x = 5
5

julia> foo.x
10

julia> getproperty(value::Foo, symbol::Symbol) = symbol == :y ? 1 : getfield(value, symbol)
getproperty (generic function with 50 methods)

julia> foo.x
10

julia> foo.y
1
1 Like

thanks, but instead of Foo there must be module M

sorry for my english,

this is a solution:

function Base.setproperty!(m::Module, p::Symbol, v)
    println("variable $p changed on $v in module $m")
    @eval m $p = $v  # waiting for julia 1.9 and will use setglobal!()
end;
1 Like