Skip to content

Commit 3ad998f

Browse files
committed
Implement @kwredef
Closes #3.
1 parent 5280a5d commit 3ad998f

File tree

2 files changed

+70
-2
lines changed

2 files changed

+70
-2
lines changed

docs/src/index.md

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ CurrentModule = RedefStructs
66

77
Documentation for [RedefStructs.jl](https://github.com/FedericoStra/RedefStructs.jl).
88

9-
This package provides the macros [`@redef`](@ref) and [`@redef_print`](@ref),
9+
This package provides the macros [`@redef`](@ref), [`@redef_print`](@ref), and [`@kwredef`](@ref)
1010
which allow to create `struct`ures which are redefinable.
1111

1212
```@contents
@@ -55,6 +55,27 @@ julia> S(42).n
5555
42
5656
```
5757

58+
Using [`@redef`](@ref):
59+
60+
```jldoctest
61+
julia> using RedefStructs
62+
63+
julia> @kwredef struct S
64+
s::String = "<empty>"
65+
end
66+
67+
julia> S("Hello").s
68+
"Hello"
69+
70+
julia> @kwredef mutable struct S
71+
a::Int = 0
72+
b::Int
73+
end
74+
75+
julia> S(b=42).a
76+
0
77+
```
78+
5879
## Library
5980

6081
```@index

src/RedefStructs.jl

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module RedefStructs
22

3-
export @redef, @redef_print
3+
export @redef, @redef_print, @kwredef
44

55
@doc """
66
@redef [mutable] struct S [<: A]
@@ -94,6 +94,53 @@ macro redef_print(struct_def)
9494
end)
9595
end
9696

97+
@doc """
98+
@kwredef [mutable] struct S [<: A]
99+
...
100+
end
101+
102+
Define a structure in a manner that allows redefinitions, using `Base.@kwdef`.
103+
104+
Behind the scenes, this creates a "secret" structure with
105+
[`gensym`](https://docs.julialang.org/en/v1/base/base/#Base.gensym)
106+
and assigns `S` to its name.
107+
108+
See also [`@redef`](@ref) and `Base.@kwdef`.
109+
110+
# Examples
111+
112+
```jldoctest
113+
julia> using RedefStructs
114+
115+
julia> @kwredef struct S
116+
s::String = "<empty>"
117+
end
118+
119+
julia> S("Hello").s
120+
"Hello"
121+
122+
julia> @kwredef mutable struct S
123+
a::Int = 0
124+
b::Int
125+
end
126+
127+
julia> S(b=42).a
128+
0
129+
```
130+
"""
131+
macro kwredef(struct_def)
132+
name = struct_def_name(struct_def)
133+
real_name = gensym(name)
134+
struct_def = :(Base.@kwdef $(replace!(struct_def, name, real_name)))
135+
fix_name = :(Base.unwrap_unionall($real_name).name.name = $(QuoteNode(name)))
136+
esc(quote
137+
$struct_def
138+
$fix_name
139+
$name = $real_name # this should be `const $name = $real_name`
140+
nothing # avoid returning the new struct
141+
end)
142+
end
143+
97144
"""
98145
struct_def_name(struct_def)
99146

0 commit comments

Comments
 (0)