Mutable field in immutable type

question

#1

I sometimes need to change the value in a single field of an instance of an immutable type. This is especially useful when an instance of this type is spread around different places and I need to update one of its values. This way the update occurs everywhere this instance sits, because it’s the same instance.
The way I accomplish this is by wrapping that specific field in a Vector:

julia> immutable A
           x::Int
           y::Vector{Int} # wrap it
       end
julia> a = A(1,[1])
# a lives in all sorts of places
julia> b = Dict(:b => a)
julia> c = [a, a, b]
julia> println(a, b, c) # the `y`field is equal to 1
A(1,[1])Dict(:b=>A(1,[1]))Any[A(1,[1]),A(1,[1]),Dict(:b=>A(1,[1]))]
julia> a.y[1] = 2
julia> println(a, b, c) # the `y`field is equal to 2, everywhhere!
A(1,[2])Dict(:b=>A(1,[2]))Any[A(1,[2]),A(1,[2]),Dict(:b=>A(1,[2]))]

Is there a better way to do this?


Setting individual fields for struct in array
#2

Use a mutable type that wraps all the fields you need to mutate. If you only have one, you can abuse Base.RefValue.


#3

Sorry, not sure I understand what you mean:

Use a mutable type that wraps all the fields you need to mutate.

Wrap them in what, a Vector?

If you only have one, you can abuse Base.RefValue.

Could you please specify how I’d “abuse” Base.RefValue?

Thanks!


#4

For the abuse:

immutable A
x::Int
y::Base.RefValue{Int}
end

Why call it abuse? Because there is an ongoing discussion about what Ref/RefValue should be used for…

For the wrapping:

immutable A
x::Int
mutable1::Int
mutable2::Int
end

should become:

type MyMutables
mutable1::Int
mutable2::Int
end
immutable A
x::Int
mutables::MyMutables
end