From c10868e9a2cdc86ea4044131b6be290ef02cd79b Mon Sep 17 00:00:00 2001 From: Daniel Matz Date: Fri, 17 Oct 2025 13:21:43 -0500 Subject: [PATCH] Implement setindex for Base.ImmutableDict The design of Base.ImmutableDict allows the same key to be added again, which shadows the previously added value. Unfortunately, it still prints out all of the entries, including repeated keys. I thought this might be confusing, so I implemented it to remove the value if the key exists and then add the new value. Closes #216 --- src/setindex.jl | 4 ++++ test/test_setindex.jl | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/setindex.jl b/src/setindex.jl index 04203be3..ed378817 100644 --- a/src/setindex.jl +++ b/src/setindex.jl @@ -24,6 +24,10 @@ Base.@propagate_inbounds function setindex(d0::AbstractDict, v, k) return d end +function setindex(d::Base.ImmutableDict, v, k) + Base.ImmutableDict(d, k => v) +end + # may be added to Base in https://github.com/JuliaLang/julia/pull/46453 @inline function setindex(t::Tuple, v, inds::AbstractVector{<:Integer}) ntuple(length(t)) do i diff --git a/test/test_setindex.jl b/test/test_setindex.jl index f8f4bac4..fccf4ea7 100644 --- a/test/test_setindex.jl +++ b/test/test_setindex.jl @@ -43,6 +43,10 @@ end @test Accessors.setindex(d, 30, "c") ==ₜ Dict(:a=>1, :b=>2, "c"=>30) @test Accessors.setindex(d, 10.0, :a) ==ₜ Dict(:a=>10.0, :b=>2.0) + d = Base.ImmutableDict(:a => 1, :b => 2) + @test @set(d[:a] = 3) == Base.ImmutableDict(:a => 1, :b => 2, :a => 3) + @test @set(d[:c] = 3) == Base.ImmutableDict(:a => 1, :b => 2, :c => 3) + nt = (a=1, b='2') @test @set(nt[:a] = "abc") == (a="abc", b='2') @test @set(nt[1] = "abc") == (a="abc", b='2')