Suppose I have a struct where I am mutating one of the fields (say it is a Vector) like
struct A
x::Vector
end
a = A([1, 2])
a.x[1] = 0
and I want to have some sort of flag to indicate whether I have mutated a.x. How can I do this? Currently, I am doing
struct A
x::Vector
flag::Vector{Bool}
end
where A.flag is just a 1-element vector so that it is mutable and I can update it. I’m sure this is not the best way to do this.
I am aware of Accessors.jl, but I don’t want to copy/construct a new object when I update. I also looked at Observables.jl, but the docs are sparse and it is not obvious to me how I would implement this. Any ideas and help is appreciated!
I parameterized the struct A with T so that x will have a concrete type Vector{T}. x::Vector by itself is an abstract type and is not very compiler friendly.
Ref is basically a 0-dimensional array with one element. It is slightly more space efficient than your version. Here I used Base.RefValue since it is a concrete type while Ref is an abstract type.
I might go further and implement Base.setindex! for your new type. Here you can do an indexed assignment on a directly, and this will be forwarded to modify the field x. While doing so, it will set the flag.
julia> function Base.setindex!(A, X, inds...)
setindex!(A.x, X, inds...)
A.flag[] = true
end
julia> a = A([1,2])
A{Int64}([1, 2], Base.RefValue{Bool}(false))
julia> a[1] = 3
3
julia> a
A{Int64}([3, 2], Base.RefValue{Bool}(true))