You basically want to create your own macro here.
See Metaprogramming · The Julia Language
@with_kw @fill_params HYPname struct HHsol
aP::Array{Float64,2}
cP::Array{Float64,2}
end
To start let’s create an expression:
julia> e =:(
struct HHsol
aP::Array{Float64,2}
cP::Array{Float64,2}
end)
:(struct HHsol
#= REPL[14]:3 =#
aP::Array{Float64, 2}
#= REPL[14]:4 =#
cP::Array{Float64, 2}
end)
julia> typeof(e)
Expr
julia> e.head
:struct
julia> e.args
3-element Vector{Any}:
false
:HHsol
quote
#= REPL[14]:3 =#
aP::Array{Float64, 2}
#= REPL[14]:4 =#
cP::Array{Float64, 2}
end
julia> e.args[2]
:HHsol
julia> e.args[3]
quote
#= REPL[14]:3 =#
aP::Array{Float64, 2}
#= REPL[14]:4 =#
cP::Array{Float64, 2}
end
We see that we primarily want to edit argument 3 which is a quote block.
julia> e2 = e.args[3]
quote
#= REPL[14]:3 =#
aP::Array{Float64, 2}
#= REPL[14]:4 =#
cP::Array{Float64, 2}
end
julia> typeof(e2)
Expr
julia> e2.head
:block
julia> e2.args
4-element Vector{Any}:
:(#= REPL[14]:3 =#)
:(aP::Array{Float64, 2})
:(#= REPL[14]:4 =#)
:(cP::Array{Float64, 2})
julia> e2.args[3]
:(#= REPL[14]:4 =#)
julia> e2.args[2]
:(aP::Array{Float64, 2})
julia> e2.args[2].head
:(::)
julia> e2.args[2].args
2-element Vector{Any}:
:aP
:(Array{Float64, 2})
Now we need to figure how we want to modify this expression. To do so we create the expression that we want and examine it first.
julia> target = :(aP::Array{Float64, 2} = fill(1.0,HYPname.na, HYPname.nz))
:(aP::Array{Float64, 2} = fill(1.0, HYPname.na, HYPname.nz))
julia> target.head
:(=)
julia> target.args
2-element Vector{Any}:
:(aP::Array{Float64, 2})
:(fill(1.0, HYPname.na, HYPname.nz))
We see that all we want to do is replace the ::
expression with a :(=)
expression containing it. Let’s write a function to do that.
julia> function fill_individual_param(param_expr, s)
Expr(
:(=),
param_expr,
:(fill(1.0, $s.na, $s.nz))
)
end
fill_individual_param (generic function with 1 method)
julia> fill_individual_param(e2.args[2], :HYPname)
:(aP::Array{Float64, 2} = fill(1.0, ($(Expr(:escape, :HYPname))).na, ($(Expr(:escape, :HYPname))).nz))
julia> e2.args
4-element Vector{Any}:
:(#= REPL[13]:3 =#)
:(aP::Array{Float64, 2})
:(#= REPL[13]:4 =#)
:(cP::Array{Float64, 2})
julia> [isa(param, Expr) ? fill_individual_param(param, :HYPname) : param for param in e2.args]
4-element Vector{Any}:
:(#= REPL[13]:3 =#)
:(aP::Array{Float64, 2} = fill(1.0, ($(Expr(:escape, :HYPname))).na, ($(Expr(:escape, :HYPname))).nz))
:(#= REPL[13]:4 =#)
:(cP::Array{Float64, 2} = fill(1.0, ($(Expr(:escape, :HYPname))).na, ($(Expr(:escape, :HYPname))).nz))
Now we can use this replace the args of the quote block.
julia> e.args[3].args = [isa(param, Expr) ? fill_individual_param(param, :HYPname) : param for param in e2.args]
4-element Vector{Any}:
:(#= REPL[13]:3 =#)
:(aP::Array{Float64, 2} = fill(1.0, ($(Expr(:escape, :HYPname))).na, ($(Expr(:escape, :HYPname))).nz))
:(#= REPL[13]:4 =#)
:(cP::Array{Float64, 2} = fill(1.0, ($(Expr(:escape, :HYPname))).na, ($(Expr(:escape, :HYPname))).nz))
julia> e
:(struct HHsol
#= REPL[13]:3 =#
aP::Array{Float64, 2} = fill(1.0, ($(Expr(:escape, :HYPname))).na, ($(Expr(:escape, :HYPname))).nz)
#= REPL[13]:4 =#
cP::Array{Float64, 2} = fill(1.0, ($(Expr(:escape, :HYPname))).na, ($(Expr(:escape, :HYPname))).nz)
end)
We can then turn that into a function:
julia> function fill_params(e, s, m)
e.args[3].args = [isa(param, Expr) ? fill_individual_param(param, s) : param for param in e.args[3].args]
return Parameters.with_kw(e, m, true)
end
fill_params (generic function with 1 method)
julia> fill_params(
:(struct HHsol
aP::Array{Float64,2}
cP::Array{Float64,2}
end),
:HYPname,
@__MODULE__
)
quote
Base.@__doc__ struct HHsol
"Default: fill(1.0, HYPname.na, HYPname.nz)"
aP::Array{Float64, 2}
"Default: fill(1.0, HYPname.na, HYPname.nz)"
cP::Array{Float64, 2}
HHsol(; aP = fill(1.0, HYPname.na, HYPname.nz), cP = fill(1.0, HYPname.na, HYPname.nz)) = begin
#= C:\Users\kittisopikulm\.julia\packages\Parameters\MK0O4\src\Parameters.jl:493 =#
HHsol(aP, cP)
end
HHsol(aP, cP) = begin
#= C:\Users\kittisopikulm\.julia\packages\Parameters\MK0O4\src\Parameters.jl:505 =#
new(aP, cP)
end
end
()
()
begin
HHsol(pp::HHsol; kws...) = begin
(Parameters).reconstruct(pp, kws)
end
HHsol(pp::HHsol, di::(Parameters).AbstractDict) = begin
(Parameters).reconstruct(pp, di)
end
HHsol(pp::HHsol, di::Vararg{Tuple{Symbol, Any}}) = begin
(Parameters).reconstruct(pp, di)
end
end
function Base.show(io::IO, p::HHsol)
if get(io, :compact, false) || get(io, :typeinfo, nothing) == HHsol
Base.show_default(IOContext(io, :limit => true), p)
else
dump(IOContext(io, :limit => true), p, maxdepth = 1)
end
end
macro unpack_HHsol(ex)
esc((Parameters)._unpack(ex, Any[:aP, :cP]))
end
begin
macro pack_HHsol()
esc((Parameters)._pack_new(HHsol, Any[:aP, :cP]))
end
end
HHsol
end
Now we can turn that function into a macro:
julia> macro fill_params(s, e)
esc(fill_params(e, s, __module__))
end
@fill_params (macro with 1 method)
julia> @macroexpand @fill_params(HYPname,struct HHsol
aP::Array{Float64,2}
cP::Array{Float64,2}
end)
quote
begin
$(Expr(:meta, :doc))
struct HHsol
"Default: fill(1.0, HYPname.na, HYPname.nz)"
aP::Array{Float64, 2}
"Default: fill(1.0, HYPname.na, HYPname.nz)"
cP::Array{Float64, 2}
HHsol(; aP = fill(1.0, HYPname.na, HYPname.nz), cP = fill(1.0, HYPname.na, HYPname.nz)) = begin
HHsol(aP, cP)
end
HHsol(aP, cP) = begin
new(aP, cP)
end
end
end
()
()
begin
HHsol(pp::HHsol; kws...) = begin
(Parameters).reconstruct(pp, kws)
end
HHsol(pp::HHsol, di::(Parameters).AbstractDict) = begin
(Parameters).reconstruct(pp, di)
end
HHsol(pp::HHsol, di::Vararg{Tuple{Symbol, Any}}) = begin
(Parameters).reconstruct(pp, di)
end
end
function Base.show(io::IO, p::HHsol)
if get(io, :compact, false) || get(io, :typeinfo, nothing) == HHsol
Base.show_default(IOContext(io, :limit => true), p)
else
dump(IOContext(io, :limit => true), p, maxdepth = 1)
end
end
macro unpack_HHsol(ex)
esc((Parameters)._unpack(ex, Any[:aP, :cP]))
end
begin
macro pack_HHsol()
esc((Parameters)._pack_new(HHsol, Any[:aP, :cP]))
end
end
HHsol
end
We can then use it as follows.
julia> HYPname = (; na = 5, nz = 3)
(na = 5, nz = 3)
julia> @fill_params(HYPname,struct HHsol
aP::Array{Float64,2}
cP::Array{Float64,2}
end)
HHsol
julia> HYPname = (; na = 5, nz = 3)
(na = 5, nz = 3)
julia> HHsol()
HHsol
aP: Array{Float64}((5, 3)) [1.0 1.0 1.0; 1.0 1.0 1.0; … ; 1.0 1.0 1.0; 1.0 1.0 1.0]
cP: Array{Float64}((5, 3)) [1.0 1.0 1.0; 1.0 1.0 1.0; … ; 1.0 1.0 1.0; 1.0 1.0 1.0]
julia> HYPname = (; na = 4, nz = 9)
(na = 4, nz = 9)
julia> HHsol()
HHsol
aP: Array{Float64}((4, 9)) [1.0 1.0 … 1.0 1.0; 1.0 1.0 … 1.0 1.0; 1.0 1.0 … 1.0 1.0; 1.0 1.0 … 1.0 1.0]
cP: Array{Float64}((4, 9)) [1.0 1.0 … 1.0 1.0; 1.0 1.0 … 1.0 1.0; 1.0 1.0 … 1.0 1.0; 1.0 1.0 … 1.0 1.0]```