jonniedie / ComponentArrays.jl

Arrays with arbitrarily nested named components.
MIT License
287 stars 34 forks source link

mutability of ComponentArrays constructed from Dict objects #203

Closed slwu89 closed 1 year ago

slwu89 commented 1 year ago

Hi,

It appears that ComponentArrays built from Dicts are not mutable, see my example below. Is this intended behavior?

using ComponentArrays
cell_ic = [20.0,1.0,20.0]
cells_state = ComponentArray(
    Dict{Symbol,typeof(cell_ic)}([Symbol(i) => cell_ic for i in 1:3])
)
cells_state[Symbol(1)]
cells_state[Symbol(1)][1] = -500.0
cells_state[Symbol(1)]

I'm on package version ComponentArrays v0.13.9. Thanks!

jonniedie commented 1 year ago

It's not a Dict thing, it's just because indexing into a ComponentArray (or any array) creates a new array. So doing

cells_state[Symbol(1)][1] = -500.0

is first creating a new array with cells_state[Symbol(1)] and then setting the first element to -500.0. I think the thing that sometimes catches people off guard about this with ComponentArrays is that if you were doing this with "dot" property access, it would work as expected. So for example,

julia> x = ComponentArray(a = cell_ic, b = cell_ic, c = cell_ic);

julia> x.a[1] = -500.0;

julia> x
ComponentVector{Float64}(a = [-500.0, 1.0, 20.0], b = [20.0, 1.0, 20.0], c = [20.0, 1.0, 20.0])

This is intended behavior, although admittedly it's a little counterintuitive at first. The main issue is that getproperty purposely works differently than getindex for ComponentArrays. It used to be the case that they were the same, but it got confusing that getindex worked differently for ComponentArrays than other array types because it created a view instead of a new array.

slwu89 commented 1 year ago

Thanks @jonniedie, I see now that it's explained in the Indexing Behavior section of the docs. Feel free to close!