# Modifying internal fields inside a nested hierarchy

**URL:** <https://discourse.julialang.org/t/modifying-internal-fields-inside-a-nested-hierarchy/32263>\
**Category:** General Usage\
**Created:** [December 14, 2019, 3:48am UTC](https://discourse.julialang.org/t/modifying-internal-fields-inside-a-nested-hierarchy/32263 "2019-12-14T03:48:29Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)\
**Post date:** [December 14, 2019, 3:48am UTC](https://discourse.julialang.org/t/modifying-internal-fields-inside-a-nested-hierarchy/32263/1 "2019-12-14T03:48:29Z")

</div>

Suppose I have the following situtation with a nested hierarchy:

```julia
julia> mutable struct Foo
           x
       end

julia> struct Bar
           y::Vector{Foo}
       end

julia> b = Bar([Foo(1), Foo(2)])
Bar(Foo[Foo(1), Foo(2)])

julia> function modify!(b::Bar, w, structure)
      ## what should go here?
       end
modify! (generic function with 1 method)

```

I would like to write the function `modify!` to modify the internal elements of the `Foo` objects by replacing them with the values inside the `Vector` `w`.

The catch is that `modify!` should not need to know _anything_ about the internal structure. Rather I would like to pass in a `structure` thing like a `Vector` of `Ref`s that point to the internal elements that I want to change. But a `Vector` of `Ref`s doesn’t seem to work.

Is there a solution to this?

(This is simplified from a real problem with a deeper hierarchy. The `modify!` function needs to work on objects with different internal structures.)

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [December 14, 2019, 4:53am UTC](https://discourse.julialang.org/t/modifying-internal-fields-inside-a-nested-hierarchy/32263/2 "2019-12-14T04:53:47Z")

</div>

Some resources

> **[GitHub - zenna/Lens.jl: Lens.jl is a simple Julia library to inspect the...](https://github.com/zenna/Lens.jl)**
>
> Lens.jl is a simple Julia library to inspect the runtime behaviour of your programs, with minimal interference to the program itself. - GitHub - zenna/Lens.jl: Lens.jl is a simple Julia library to ...

> **[GitHub - jw3126/Setfield.jl: Update deeply nested immutable structs.](https://github.com/jw3126/Setfield.jl)**
>
> Update deeply nested immutable structs. Contribute to jw3126/Setfield.jl development by creating an account on GitHub.

---

<div class="post-metadata">

**Author:** ![anon92994695](https://avatars.discourse-cdn.com/v4/letter/a/ce7236/32.png) [@anon92994695](https://discourse.julialang.org/u/anon92994695)\
**Post date:** [December 14, 2019, 11:52am UTC](https://discourse.julialang.org/t/modifying-internal-fields-inside-a-nested-hierarchy/32263/3 "2019-12-14T11:52:27Z")

</div>

there’s a lot of ways to do it… It’s not fun unless this is how your brain works! I wrote a decision tree method like this and it was hideously slow, although elegant via LOC. Julia just doesn’t like function calls on deeply recursive structs :/. I think the tidy solution is to break out the structure into a graph where each node is the same type for traversing the hierarchical mess, and has pointers to the actual object which is in some sort of a hashed list or something. I’d love to hear a counter argument to that, because this has befuddled me!

Anyways, an easy way, without restructuring things, would be to write a recursive function that scans a struct for depth and type and modifies as it goes. You can make a modify function that traverse the nodes recursively or using a while loop or whatever, checks the reference state modifies in place and keeps going. Maybe something like this(not real code)? dunno

```julia
fn = x -> istype(x, Array) ? push!(x, "123") : x

function modify(NestedMess::Any, fn) 
  if terminal node
         fn(node)
         return nothing
   else  
         modify.(NestedMess, fn)
    end
end

```

The alternative is to know exactly where you wish to modify certain things in the struct (not so fun).
