Skip to content

Commit 0f86996

Browse files
committed
clean up
1 parent 83b5bb8 commit 0f86996

File tree

2 files changed

+59
-82
lines changed

2 files changed

+59
-82
lines changed

src/optics.jl

Lines changed: 57 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -249,8 +249,36 @@ function modify(f, obj, w::If)
249249
end
250250
end
251251

252+
abstract type ObjectMap end
253+
254+
OpticStyle(::Type{<:ObjectMap}) = ModifyBased()
255+
modify(f, o, optic::ObjectMap) = mapobject(f, o, optic, Construct, nothing)
256+
257+
"""
258+
Properties()
259+
260+
Access all properties of an objects.
261+
262+
```jldoctest
263+
julia> using Accessors
264+
265+
julia> obj = (a=1, b=2, c=3)
266+
(a = 1, b = 2, c = 3)
267+
268+
julia> set(obj, Properties(), "hi")
269+
(a = "hi", b = "hi", c = "hi")
270+
271+
julia> modify(x -> 2x, obj, Properties())
272+
(a = 2, b = 4, c = 6)
273+
```
274+
Based on [`mapobject`](@ref).
275+
276+
$EXPERIMENTAL
277+
"""
278+
struct Properties <: ObjectMap end
279+
252280
"""
253-
mapproperties(f, obj)
281+
mapobject(f, obj)
254282
255283
Construct a copy of `obj`, with each property replaced by
256284
the result of applying `f` to it.
@@ -260,82 +288,63 @@ julia> using Accessors
260288
261289
julia> obj = (a=1, b=2);
262290
263-
julia> Accessors.mapproperties(x -> x+1, obj)
291+
julia> Accessors.mapobject(x -> x+1, obj)
264292
(a = 2, b = 3)
265293
```
266294
$EXPERIMENTAL
267295
"""
268-
function mapproperties(f, obj::O, handler=Construct(), itr::Nothing=nothing) where O
296+
function mapobject(f, obj::O, ::Properties, handler, itr::Nothing) where O
269297
# TODO move this helper elsewhere?
270298
pnames = propertynames(obj)
271299
if isempty(pnames)
272300
return obj
273301
else
274-
ctor = constructorof(typeof(obj))
275302
new_props = map(pnames) do p
276303
f(getproperty(obj, p))
277304
end
278305
ctr = _constructor(handler, O)
279306
return ctr(new_props...)
280307
end
281308
end
282-
function mapproperties(f, obj::O, handler, itr::Int) where O
309+
function mapobject(f, obj::O, ::Properties, handler, itr::Int) where O
283310
pnames = propertynames(obj)
284311
if isempty(pnames)
285-
return _maybeitr(obj, itr)
312+
return obj, itr
286313
else
287314
# TODO: this is too slow
288315
new_props, itr = reduce(pnames; init=((), itr)) do (vals, itr), p
289316
val, itr = f(getproperty(obj, p), itr)
290317
(vals..., val), itr
291318
end
292319
ctr = _constructor(handler, O)
293-
return _maybeitr(ctr(new_props...), itr)
320+
return ctr(new_props...), itr
294321
end
295322
end
296323

297324
"""
298-
Properties()
325+
Fields()
299326
300-
Access all properties of an objects.
327+
Access all fields of an objects.
301328
302329
```jldoctest
303330
julia> using Accessors
304331
305332
julia> obj = (a=1, b=2, c=3)
306333
(a = 1, b = 2, c = 3)
307334
308-
julia> set(obj, Properties(), "hi")
335+
julia> set(obj, Fields(), "hi")
309336
(a = "hi", b = "hi", c = "hi")
310337
311-
julia> modify(x -> 2x, obj, Properties())
338+
julia> modify(x -> 2x, obj, Fields())
312339
(a = 2, b = 4, c = 6)
313340
```
314-
Based on [`mapproperties`](@ref).
341+
Based on [`mapfields`](@ref).
315342
316343
$EXPERIMENTAL
317344
"""
318-
struct Properties end
319-
OpticStyle(::Type{<:Properties}) = ModifyBased()
320-
modify(f, o, ::Properties) = mapproperties(f, o)
321-
322-
"""
323-
mapfields(f, obj)
324-
325-
Construct a copy of `obj`, with each fields replaced by
326-
the result of applying `f` to it.
327-
328-
```jldoctest
329-
julia> using Accessors
330-
331-
julia> obj = (a=1, b=2);
345+
struct Fields <: ObjectMap end
332346

333-
julia> Accessors.mapfields(x -> x+1, obj)
334-
(a = 2, b = 3)
335-
```
336-
$EXPERIMENTAL
337-
"""
338-
@generated function mapfields(f, obj::O, handler::H=Construct(), itr::I=nothing) where {O,H,I}
347+
@generated function mapobject(f, obj::O, ::Fields, handler::H=Construct(), itr::I=nothing) where {O,H,I}
339348
# TODO: This is how Flatten.jl works, but it's not really
340349
# correct use of ConstructionBase as it assumers properties=fields
341350
fnames = fieldnames(O)
@@ -385,31 +394,6 @@ end
385394
_maybeitr(x, ::Nothing) = x
386395
_maybeitr(x, itr) = x, itr
387396

388-
"""
389-
Fields()
390-
391-
Access all fields of an objects.
392-
393-
```jldoctest
394-
julia> using Accessors
395-
396-
julia> obj = (a=1, b=2, c=3)
397-
(a = 1, b = 2, c = 3)
398-
399-
julia> set(obj, Fields(), "hi")
400-
(a = "hi", b = "hi", c = "hi")
401-
402-
julia> modify(x -> 2x, obj, Fields())
403-
(a = 2, b = 4, c = 6)
404-
```
405-
Based on [`mapfields`](@ref).
406-
407-
$EXPERIMENTAL
408-
"""
409-
struct Fields end
410-
OpticStyle(::Type{<:Fields}) = ModifyBased()
411-
modify(f, o, ::Fields) = mapfields(f, o)
412-
413397
"""
414398
Recursive(descent_condition, optic)
415399
@@ -484,11 +468,10 @@ Base.@propagate_inbounds function set(obj, lens::DynamicIndexLens, val)
484468
end
485469

486470
"""
487-
Query(select, ignore)
471+
Query(select, descend)
488472
489-
Query an object recursively, choosing fields based on the single-argument
490-
function `select` and ignoring objects based on another single-argument
491-
function `ignore`.
473+
Query an object recursively, choosing fields when `select`
474+
returns `true`, and descending when `descend`.
492475
493476
```jldoctest
494477
julia> using Accessors
@@ -515,43 +498,37 @@ end
515498
Query(select, descend = x -> true) = Query(select, descend, Fields())
516499
Query(; select=Any, descend=x -> true, optic=Fields()) = Query(select, descend, optic)
517500

518-
_inner(optic::ComposedOptic) = optic.inner
519-
_inner(optic::Fields) = optic
520-
_inner(optic::Properties) = optic
521-
522501
function (q::Query)(obj)
523-
_query(obj, _inner(q.optic), Splat(), nothing) do o
502+
mapobject(obj, _inner(q.optic), Splat(), nothing) do o
524503
if q.select_condition(o)
525504
(_getouter(o, q.optic),)
526505
elseif q.descent_condition(o)
527-
q(o)
506+
q(o) # also a tuple
528507
else
529508
()
530509
end
531510
end
532511
end
533512

534-
_getouter(o, optic::ComposedOptic) = optic.outer(o)
535-
_getouter(o, optic) = o
536-
537-
_set(obj, q::Query, val, ::SetBased) = _setquery(obj, q::Query, (val, 1))[1]
513+
set(obj, q::Query, vals) = _set(obj, q::Query, (vals, 1))[1]
538514

539-
function _setquery(obj, q::Query, (val, itr))
540-
_query(obj, _inner(q.optic), Construct(), itr) do o, itr
515+
function _set(obj, q::Query, (vals, itr))
516+
mapobject(obj, _inner(q.optic), Construct(), itr) do o, itr
541517
if q.select_condition(o)
542-
_setouter(o, q.optic, val[itr]), itr + 1
518+
_setouter(o, q.optic, vals[itr]), itr + 1
543519
elseif q.descent_condition(o)
544-
_setquery(o, q, (val, itr))
520+
_set(o, q, (vals, itr))
545521
else
546522
o, itr
547523
end
548524
end
549525
end
550526

551-
_setouter(o, optic::ComposedOptic, v) = set(o, optic.outer, v)
552-
_setouter(o, optic, v) = v
553-
554527
modify(f, obj, q::Query) = set(obj, q, map(f, q(obj)))
555528

556-
_query(f, o, ::Fields, handler, itr) = mapfields(f, o, handler, itr)
557-
_query(f, o, ::Properties, handler, itr) = mapproperties(f, o, handler, itr)
529+
_inner(optic::ComposedOptic) = optic.inner
530+
_inner(optic) = optic
531+
_getouter(o, optic::ComposedOptic) = optic.outer(o)
532+
_getouter(o, optic) = o
533+
_setouter(o, optic::ComposedOptic, v) = set(o, optic.outer, v)
534+
_setouter(o, optic, v) = v

test/test_queries.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,14 @@ println("get")
2929
println("set")
3030
# Need a wrapper so we don't have to pass in the starting iterator
3131
@btime Accessors.set($obj, $lens, $vals)
32+
@btime Accessors._set($obj, $lens, ($vals, 1))[1]
3233
@btime Accessors.set($obj, $slowlens, $vals)
3334
Accessors.set(obj, lens, vals)
3435
@test Accessors.set(obj, lens, vals) ==
3536
Accessors.set(obj, lens, vals) ==
3637
(7, (a=1.0, b=2.0f0), ("3", 4, 5.0), ((a=2.0,), [1]))
3738

38-
# using ProfileView
39-
# @profview for i in 1:1000000 Accessors.set(obj, lens, vals) end
39+
@code_warntype Accessors.set(obj, lens, vals)
4040

4141
println("unstable set")
4242
unstable_lens = Accessors.Query(select=x -> x isa Float64 && x > 2, descend=x -> x isa NamedTuple)

0 commit comments

Comments
 (0)