Skip to content

Commit

Permalink
Add at-set!! macro
Browse files Browse the repository at this point in the history
Note: I have to exclude get/set from ambiguity checks again.  So, a
part of commit 52218dd had to be
reverted.
  • Loading branch information
tkf committed Nov 5, 2019
1 parent 92a6b8f commit 27bdfb8
Show file tree
Hide file tree
Showing 9 changed files with 122 additions and 3 deletions.
2 changes: 2 additions & 0 deletions Project.toml
Expand Up @@ -10,6 +10,7 @@ Future = "9fa8497b-333b-5362-9e8d-4d0656e87820"
InitialValues = "22cec73e-a1b8-11e9-2c92-598750a2cf9c"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
Requires = "ae029012-a4dd-5104-9daa-d747884805df"
Setfield = "efcf1570-3423-57d1-acb7-fd33fddbac46"
Tables = "bd369af6-aec1-5ad0-b16a-f7cc5008161c"
ZygoteRules = "700de1a5-db45-46bc-99cf-38207098b444"

Expand All @@ -18,6 +19,7 @@ Compat = "2"
ConstructionBase = "0.1"
InitialValues = "0.2"
Requires = "0.5"
Setfield = "0.5.1"
Tables = "0.2"
ZygoteRules = "0.1, 0.2"
julia = "1.0"
Expand Down
10 changes: 9 additions & 1 deletion docs/Manifest.toml
@@ -1,7 +1,7 @@
# This file is machine-generated - editing it directly is not advised

[[BangBang]]
deps = ["Compat", "ConstructionBase", "Future", "InitialValues", "LinearAlgebra", "Requires", "Tables", "ZygoteRules"]
deps = ["Compat", "ConstructionBase", "Future", "InitialValues", "LinearAlgebra", "Requires", "Setfield", "Tables", "ZygoteRules"]
path = ".."
uuid = "198e06fe-97b7-11e9-32a5-e1d131e6ad66"
version = "0.3.2-DEV"
Expand Down Expand Up @@ -197,6 +197,14 @@ uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce"
[[Serialization]]
uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b"

[[Setfield]]
deps = ["ConstructionBase", "MacroTools"]
git-tree-sha1 = "17d7a3334861580d46a4578fb60acefa1376a829"
repo-rev = "master"
repo-url = "https://github.com/jw3126/Setfield.jl.git"
uuid = "efcf1570-3423-57d1-acb7-fd33fddbac46"
version = "0.5.0"

[[SharedArrays]]
deps = ["Distributed", "Mmap", "Random", "Serialization"]
uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383"
Expand Down
1 change: 1 addition & 0 deletions docs/Project.toml
Expand Up @@ -3,5 +3,6 @@ BangBang = "198e06fe-97b7-11e9-32a5-e1d131e6ad66"
ConstructionBase = "187b0558-2788-49d3-abe0-74a17ed4e7c9"
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
Setfield = "efcf1570-3423-57d1-acb7-fd33fddbac46"
StructArrays = "09ab397b-f2b6-538f-b94a-2f83cf4a842a"
TypedTables = "9d95f2ec-7b3d-5a63-8d20-e2491e220bb9"
5 changes: 5 additions & 0 deletions src/BangBang.jl
Expand Up @@ -4,6 +4,7 @@ module BangBang
@doc read(joinpath(dirname(@__DIR__), "README.md"), String) BangBang

export @!,
@set!!,
Empty,
append!!,
delete!!,
Expand All @@ -13,6 +14,7 @@ export @!,
mul!!,
pop!!,
popfirst!!,
prefermutation,
push!!,
pushfirst!!,
rmul!!,
Expand Down Expand Up @@ -45,6 +47,9 @@ include("macro.jl")
include("dataframes_impl.jl")
include("zygote.jl")

include("setfield.jl")
using .SetfieldImpl: @set!!, prefermutation

function __init__()
@require StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" begin
include("staticarrays.jl")
Expand Down
74 changes: 74 additions & 0 deletions src/setfield.jl
@@ -0,0 +1,74 @@
module SetfieldImpl

using ..BangBang: setproperty!!, setindex!!
using Setfield: ComposedLens,
ConstIndexLens,
DynamicIndexLens,
IndexLens,
Lens,
PropertyLens,
Setfield,
set

struct Lens!!{T <: Lens} <: Lens
lens::T
end

Setfield.get(obj, lens::Lens!!) = get(obj, lens.lens)

# Default to immutable:
Setfield.set(obj, lens::Lens!!, value) =
set(obj, lens.lens, value)

Setfield.set(obj, lens::Lens!!{<:ComposedLens}, value) =
set(obj, Lens!!(lens.lens.outer) Lens!!(lens.lens.inner), value)

Setfield.set(obj, ::Lens!!{<:PropertyLens{fieldname}}, value) where fieldname =
setproperty!!(obj, fieldname, value)

const SupportedIndexLens = Union{
ConstIndexLens,
DynamicIndexLens,
IndexLens,
}

indicesfor(lens::IndexLens, _) = lens.indices
indicesfor(::ConstIndexLens{I}, _) where I = I
indicesfor(lens::DynamicIndexLens, obj) = lens.f(obj)

Setfield.set(obj, lens::Lens!!{<:SupportedIndexLens}, value) =
setindex!!(obj, value, indicesfor(lens, obj)...)

"""
prefermutation(lens::Lens) :: Lens
See also [`@set!!`](@ref).
"""
prefermutation(lens::Lens) = Lens!!(lens)

"""
@set!! assignment
Like `Setfield.@set`, but prefer mutation if possible.
# Examples
```jldoctest
julia> using BangBang
julia> mutable struct Mutable
a
b
end
julia> x = orig = Mutable((x=Mutable(1, 2), y=3), 4);
julia> @set!! x.a.x.a = 10;
julia> @assert x.a.x.a == orig.a.x.a == 10
```
"""
macro set!!(ex)
Setfield.setmacro(prefermutation, ex, overwrite=true)
end

end # module
10 changes: 9 additions & 1 deletion test/Manifest.toml
Expand Up @@ -15,7 +15,7 @@ uuid = "4c88cf16-eb10-579e-8560-4a9242c79595"
version = "0.4.0"

[[BangBang]]
deps = ["Compat", "ConstructionBase", "Future", "InitialValues", "LinearAlgebra", "Requires", "Tables", "ZygoteRules"]
deps = ["Compat", "ConstructionBase", "Future", "InitialValues", "LinearAlgebra", "Requires", "Setfield", "Tables", "ZygoteRules"]
path = ".."
uuid = "198e06fe-97b7-11e9-32a5-e1d131e6ad66"
version = "0.3.2-DEV"
Expand Down Expand Up @@ -301,6 +301,14 @@ uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce"
[[Serialization]]
uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b"

[[Setfield]]
deps = ["ConstructionBase", "MacroTools"]
git-tree-sha1 = "17d7a3334861580d46a4578fb60acefa1376a829"
repo-rev = "master"
repo-url = "https://github.com/jw3126/Setfield.jl.git"
uuid = "efcf1570-3423-57d1-acb7-fd33fddbac46"
version = "0.5.0"

[[SharedArrays]]
deps = ["Distributed", "Mmap", "Random", "Serialization"]
uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383"
Expand Down
1 change: 1 addition & 0 deletions test/Project.toml
Expand Up @@ -9,6 +9,7 @@ IRTest = "c9680f28-2a59-47f6-98e4-d41620d42cd2"
InitialValues = "22cec73e-a1b8-11e9-2c92-598750a2cf9c"
InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
Setfield = "efcf1570-3423-57d1-acb7-fd33fddbac46"
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
StructArrays = "09ab397b-f2b6-538f-b94a-2f83cf4a842a"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
Expand Down
6 changes: 5 additions & 1 deletion test/test_aqua.jl
Expand Up @@ -2,7 +2,11 @@ module TestAqua

using Aqua
using BangBang
using Setfield

Aqua.test_all(BangBang)
Aqua.test_all(
BangBang;
ambiguities=(exclude=[Base.get, Setfield.set, Setfield.modify],),
)

end # module
16 changes: 16 additions & 0 deletions test/test_setfield.jl
@@ -0,0 +1,16 @@
module TestSetfield

include("preamble.jl")

mutable struct Mutable
a
b
end

@testset begin
x = orig = Mutable((x=Mutable(1, 2), y=3), 4);
@set!! x.a.x.a = 10;
@test x.a.x.a == orig.a.x.a == 10
end

end # module

0 comments on commit 27bdfb8

Please sign in to comment.