I have a context structure with many fields and want to mutate some by reinitialising, where I could do various validations. I know there is an excellent SetField.jl package, but I have only one structure, and thus, I would like to avoid introducing additional dependencies. Thus I am attempting to construct the following code with an eval:
struct Context
a::Int
b::Int
end
function Context(ctx; a=ctx.a, b=ctx.b)
return Context(a, b)
end
ctx = Context(2, 4)
new_ctx = Context(ctx, a=3)
So far the best I have come up with is using the strings and at the last stage calling Meta.parse
:
function_signature = join(["$(f)=ctx.$(f)" for f in fieldnames(Context)], ", ")
function_body = join(["$(f)" for f in fieldnames(Context)], ", ")
body = """
function Context(ctx::Context; $function_signature)
return Context($function_body)
end
"""
eval(Meta.parse(body))
But this did not work out, although the body contains the exact definition I need. I would also much prefer using expressions directly. Can someone help me with this?