Getting started
Say you have a NamedTuple
and you want to update it:
julia> x = (greeting="Hello", name="World")
(greeting = "Hello", name = "World")
julia> x.greeting = "Hi"
ERROR: setfield!: immutable struct of type NamedTuple cannot be changed
[...]
This fails, because named tuples are immutable. Instead you can use Accessors to carry out the update:
julia> using Accessors
julia> @set x.greeting = "Hi"
(greeting = "Hi", name = "World")
julia> x # still the same. Accessors did not overwrite x, it just created an updated copy
(greeting = "Hello", name = "World")
julia> x_new = @set x.greeting = "Hi" # typically you will assign a name to the updated copy
(greeting = "Hi", name = "World")
Accessors.jl does not only support NamedTuple
, but arbitrary structs and nested updates.
julia> struct HelloWorld
greeting::String
name::String
end
julia> x = HelloWorld("hi", "World")
HelloWorld("hi", "World")
julia> @set x.name = "Accessors" # update a struct
HelloWorld("hi", "Accessors")
julia> x = (a=1, b=(c=3, d=4))
(a = 1, b = (c = 3, d = 4))
julia> @set x.b.c = 10 # nested update
(a = 1, b = (c = 10, d = 4))
Accessors.jl does not only support updates of properties, but also index updates.
julia> x = (10,20,21)
(10, 20, 21)
julia> @set x[3] = 30
(10, 20, 30)
In fact Accessors.jl supports many more notions of update:
julia> x = [1,2,3];
julia> x_new = @set eltype(x) = UInt8;
julia> @show x_new;
x_new = UInt8[0x01, 0x02, 0x03]
Accessors.jl is very composable, which means different updates can be nested and combined.
julia> data = (a = (b = (1,2),), c=3)
(a = (b = (1, 2),), c = 3)
julia> @set data.a.b[end] = 20
(a = (b = (1, 20),), c = 3)
julia> @set splitext("some_file.py")[2] = ".jl"
"some_file.jl"