i try to define a function which creates a new composite based on a copy of a given composite, but with a single field changed, and without using mutable structs.
I’ve attached a code snipped which tries to solve this with a string and
eval, but I’ve realized that it is only valid in global scope. But maybe it helps to understand the intended functionality.
The final string which would be send to
eval, defining a new stuct
ChangeMe with a different input for its
:y field, is as follows:
"out = ChangeMe(inStruct.x, newValue, inStruct.z, inStruct.s)"
So does anybody have suggestions how to solve this problem? Is there a possibility to initiate such a struct without calling its name, so instead of
ChangeMe(x,y,z,s) something like
initiateStruct(typeOfThatParticularStruct, args...)? The function is supposed to be general applicable, meaning I never know the name of the composite or how many fields it actually has.
Import Test struct ChangeMe x::Int64 y::Int64 z::Int64 s::String end function cpStructWithChangedField(inStruct, chField::Symbol, newValue) # type of struct inType = typeof(inStruct) # field count and names fc = fieldcount(inType) fn = fieldnames(inType) # create new struct via meta programming metaString = String push!(metaString,"out = " * string(inType)*"(") for field in 1:fc # if chFiled is found, apply new value if fn[field] == chField push!(metaString,"newValue") else # otherwise old value from original composite push!(metaString,"inStruct."*string(fn[field])) end # add separation symbol in string if field != fc push!(metaString,", ") else # no separation after last element push!(metaString,")") end end # combine array of strings to single string metaString = join(metaString) # eval >> not working, only GLOBAL scope! eval(Meta.parse(metaString)) return out end # input composite inp = ChangeMe(1,2,3,"Hello") # expected composite exp = ChangeMe(1,99,3,"Hello") Test.@test cpStructWithChangedField(inp, :y ,99) == exp