Docstrings
Setfield.Lens
— TypeLens
A Lens
allows to access or replace deeply nested parts of complicated objects.
Example
julia> using Setfield
julia> struct T;a;b; end
julia> obj = T("AA", "BB")
T("AA", "BB")
julia> lens = @lens _.a
(@lens _.a)
julia> get(obj, lens)
"AA"
julia> set(obj, lens, 2)
T(2, "BB")
julia> obj
T("AA", "BB")
julia> modify(lowercase, obj, lens)
T("aa", "BB")
Interface
Concrete subtypes of Lens
have to implement
set(obj, lens, val)
get(obj, lens)
These must be pure functions, that satisfy the three lens laws:
@assert get(set(obj, lens, val), lens) == val
# You get what you set.
@assert set(obj, lens, get(obj, lens)) == obj
# Setting what was already there changes nothing.
@assert set(set(obj, lens, val1), lens, val2) == set(obj, lens, val2)
# The last set wins.
Base.get
— Functionget(obj, l::Lens)
Access a deeply nested part of obj
. See also Lens
.
Setfield.modify
— Functionmodify(f, obj, l::Lens)
Replace a deeply nested part x
of obj
by f(x)
. See also Lens
.
Setfield.set
— Functionset(obj, l::Lens, val)
Replace a deeply nested part of obj
by val
. See also Lens
.
Setfield.@lens
— Macro@lens
Construct a lens from a field access.
Example
julia> using Setfield
julia> struct T;a;b;end
julia> t = T("A1", T(T("A3", "B3"), "B2"))
T("A1", T(T("A3", "B3"), "B2"))
julia> l = @lens _.b.a.b
(@lens _.b.a.b)
julia> get(t, l)
"B3"
julia> set(t, l, 100)
T("A1", T(T("A3", 100), "B2"))
julia> t = ("one", "two")
("one", "two")
julia> set(t, (@lens _[1]), "1")
("1", "two")
Setfield.@set!
— Macro@set! assignment
Shortcut for obj = @set obj...
.
julia> t = (a=1,) (a = 1,)
julia> @set! t.a=2 (a = 2,)
julia> t (a = 2,)
Setfield.@set
— Macro@set assignment
Return a modified copy of deeply nested objects.
Example
julia> using Setfield
julia> struct T;a;b end
julia> t = T(1,2)
T(1, 2)
julia> @set t.a = 5
T(5, 2)
julia> t
T(1, 2)
julia> t = @set t.a = T(2,2)
T(T(2, 2), 2)
julia> @set t.a.b = 3
T(T(2, 3), 2)
Setfield.ConstIndexLens
— TypeConstIndexLens{I}
Lens with index stored in type parameter. This is useful for type-stable get
and set
operations on tuples and named tuples.
This lens can be constructed by, e.g., @lens _[$1]
. Complex expression must be wrapped with $(...)
like @lens _[$(length(xs))]
.
Examples
julia> using Setfield
julia> get((1, 2.0), @lens _[$1])
1
julia> Base.promote_op(get, typeof.(((1, 2.0), @lens _[$1]))...)
Int64
julia> Base.promote_op(get, typeof.(((1, 2.0), @lens _[1]))...) !== Int
true
Setfield.FunctionLens
— TypeFunctionLens(f)
@lens f(_)
Lens with get
method definition that simply calls f
. set
method for each function f
must be implemented manually. Use methods(set, (Any, Setfield.FunctionLens, Any))
to get a list of supported functions.
Note that FunctionLens
flips the order of composition; i.e., (@lens f(_)) ∘ (@lens g(_)) == @lens g(f(_))
.
Example
julia> using Setfield
julia> obj = ((1, 2), (3, 4));
julia> lens = (@lens first(_)) ∘ (@lens last(_))
(@lens last(first(_)))
julia> get(obj, lens)
2
julia> set(obj, lens, '2')
((1, '2'), (3, 4))
Implementation
To use myfunction
as a lens, define a set
method with the following signature:
Setfield.set(obj, ::typeof(@lens myfunction(_)), val) = ...
typeof
is used above instead of FunctionLens
because how actual type of @lens myfunction(_)
is implemented is not the part of stable API.
Base.:∘
— Methodlens₁ ∘ lens₂
compose([lens₁, [lens₂, [lens₃, ...]]])
Compose lenses lens₁
, lens₂
, ..., lensₙ
to access nested objects.
Example
julia> using Setfield
julia> obj = (a = (b = (c = 1,),),);
julia> la = @lens _.a
lb = @lens _.b
lc = @lens _.c
lens = la ∘ lb ∘ lc
(@lens _.a.b.c)
julia> get(obj, lens)
1
Setfield.lensmacro
— Methodlensmacro(lenstransform, ex::Expr)
This function can be used to create a customized variant of @lens
. It works by applying lenstransform
to the created lens at runtime.
function mytransform(lens::Lens)::Lens
...
end
macro mylens(ex)
lensmacro(mytransform, ex)
end
See also setmacro
.
Setfield.setmacro
— Methodsetmacro(lenstransform, ex::Expr; overwrite::Bool=false)
This function can be used to create a customized variant of @set
. It works by applying lenstransform
to the lens that is used in the customized @set
macro at runtime.
function mytransform(lens::Lens)::Lens
...
end
macro myset(ex)
setmacro(mytransform, ex)
end
See also lensmacro
.