Docstrings

Setfield.LensType
Lens

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.

See also @lens, set, get, modify.

source
Base.getFunction
get(obj, l::Lens)

Access a deeply nested part of obj. See also Lens.

source
Setfield.setFunction
set(obj, l::Lens, val)

Replace a deeply nested part of obj by val. See also Lens.

source
Setfield.@lensMacro
@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")
source
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,)

source
Setfield.@setMacro
@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)
source
Setfield.ConstIndexLensType
ConstIndexLens{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
source
Setfield.FunctionLensType
FunctionLens(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.

source
Base.:∘Method
lens₁ ∘ 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
source
Setfield.lensmacroMethod
lensmacro(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.

source
Setfield.setmacroMethod
setmacro(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.

source