# How to use WeakRef inside construtor?

**URL:** <https://discourse.julialang.org/t/how-to-use-weakref-inside-construtor/113405>\
**Category:** General Usage\
**Tags:** question\
**Created:** [April 23, 2024, 4:08pm UTC](https://discourse.julialang.org/t/how-to-use-weakref-inside-construtor/113405 "2024-04-23T16:08:06Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![schlichtanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/schlichtanders/32/32145_2.png) [@schlichtanders](https://discourse.julialang.org/u/schlichtanders)\
**Post date:** [April 23, 2024, 4:08pm UTC](https://discourse.julialang.org/t/how-to-use-weakref-inside-construtor/113405/1 "2024-04-23T16:08:06Z")

</div>

Hi there,  
I am trying to create a self-updating object which kills its own updating process as soon as it is finalized

```julia
mutable struct SelfUpdating
    value
    function SelfUpdating(value)
        finalize(x) = Threads.@spawn println("finalizing $x")
        spawn_task(wx) = Threads.@spawn while true
            sleep(2)
            isnothing(wx.value) && return
            println(wx.value.value)
            wx.value.value += 1
        end
        let x = new(value)
            finalizer(finalize, x)
            spawn_task(WeakRef(x))
            x
        end
    end
end

```

this unfortunately does not seem to work… I am very surprised.  
As you see I already tried to get rid of any variable reference I can imagine.

Still when assigning `sf = SelfUpdating(1)` and later `sf = nothing; GC.gc()`, it is not finalized.  
Every help is highly appreciated

---

<div class="post-metadata">

**Author:** ![danielwe](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/danielwe/32/35657_2.png) [@danielwe](https://discourse.julialang.org/u/danielwe)\
**Post date:** [April 23, 2024, 4:56pm UTC](https://discourse.julialang.org/t/how-to-use-weakref-inside-construtor/113405/2 "2024-04-23T16:56:18Z")

</div>

This appears to work:

```julia
mutable struct SelfUpdating
    value
    function SelfUpdating(value)
        finalize(x) = Threads.@spawn println("finalizing $x")
        update!(x) = (x.value += 1)
        spawn_task(wx) = Threads.@spawn while true
            sleep(2)
            isnothing(wx.value) && return
            println(wx.value.value)
            update!(wx.value)
        end
        let x = new(value)
            finalizer(finalize, x)
            spawn_task(WeakRef(x))
            x
        end
    end
end

```

Don’t ask me why, I know next to nothing about these things, I was just intrigued by the puzzle and stumbled upon a solution.

---

<div class="post-metadata">

**Author:** ![schlichtanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/schlichtanders/32/32145_2.png) [@schlichtanders](https://discourse.julialang.org/u/schlichtanders)\
**Post date:** [April 24, 2024, 8:53am UTC](https://discourse.julialang.org/t/how-to-use-weakref-inside-construtor/113405/3 "2024-04-24T08:53:25Z")

</div>

This is really impressive. If I see it correctly, you put the `+=` update into the `update!` function. That looks totally unreasonable that this works 😃  
EDIT: Thank you so much!!! I am super happy to have a workaround now 🙂

Hence I guess this is a bug in reference tracking. Does someone know?

---

<div class="post-metadata">

**Author:** ![danielwe](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/danielwe/32/35657_2.png) [@danielwe](https://discourse.julialang.org/u/danielwe)\
**Post date:** [April 24, 2024, 4:14pm UTC](https://discourse.julialang.org/t/how-to-use-weakref-inside-construtor/113405/4 "2024-04-24T16:14:46Z")

</div>

What surprises me, given that the above works, is that the following does not work:

```julia
mutable struct SelfUpdating
    value
    function SelfUpdating(value)
        finalize(x) = Threads.@spawn println("finalizing $x")
        spawn_task(wx) = Threads.@spawn while true
            sleep(2)
            isnothing(wx.value) && return
            println(wx.value.value)
            let x = wx.value
                x.value += 1
            end
        end
        let x = new(value)
            finalizer(finalize, x)
            spawn_task(WeakRef(x))
            x
        end
    end
end

```

Specifically, `wx.value.value += 1` lowers to `wx.value.value = wx.value.value + 1`, which is slightly different from `x = wx.value; x.value += 1` in that the latter only calls `getproperty(wx, :value)` once while the former does so twice (once on each side of the equals sign). (Not that this should matter for reference counting, but at least that’s a clear semantic difference.) But from all my experimenting I’m not able to make it work with any such combination of reorganizing statements and adding `let`, it really seems that a function barrier is necessary.
