I'm working with arrays of immutables each containing several fields. Now
creating new immutables based on old ones has become a real pain:
old = myarray[i]
myarray[i].foo = myimmutable(old.foo, bar, old.x, old.y, etc.)
imagine this for 15 fields...!
So I made a macro to ease this, it can be used like this:
@set myarray i bar=newbar x=newx
and the rest of the parameters remain the same. See code below.
The problem is that although I can autogenerate the macro for different
types, I cannot use the same function name @set for all types. Each type
has to have its own special macro!
The reason is that this macro requires knowledge of the types it is working
on, something missing at macro "runtime". While stagedfunctions do have
type information, they miss the array symbol name.
Maybe a "stagedmacro" could help ;)
Do you know how could this be solved?
Thanks!
immutable IM
aa::Float64
bb::Float64
cc::Float64
dd::Float64
ee::Float64
ff::Float64
gg::Float64
hh::Float64
ii::Float64
jj::Float64
kk::Float64
ll::Float64
end
macro set(ARR, IX, KV...)
d = [p.args[1]=>p.args[2] for p in KV]
aa = get(d,:aa,:($ARR[$IX].aa))
bb = get(d,:bb,:($ARR[$IX].bb))
cc = get(d,:cc,:($ARR[$IX].cc))
dd = get(d,:dd,:($ARR[$IX].dd))
ee = get(d,:ee,:($ARR[$IX].ee))
ff = get(d,:ff,:($ARR[$IX].ff))
gg = get(d,:gg,:($ARR[$IX].gg))
hh = get(d,:hh,:($ARR[$IX].hh))
ii = get(d,:ii,:($ARR[$IX].ii))
jj = get(d,:jj,:($ARR[$IX].jj))
kk = get(d,:kk,:($ARR[$IX].kk))
ll = get(d,:ll,:($ARR[$IX].ll))
quote
@inbounds $ARR[$IX] =
IM($aa,$bb,$cc,$dd,$ee,$ff,$gg,$hh,$ii,$jj,$kk,$ll)
end
end
this is used as follows:
a = [IM(1,1,1,1,1,1,1,1,1,1,1,1),
IM(1,1,1,1,1,1,1,1,1,1,1,1),
IM(1,1,1,1,1,1,1,1,1,1,1,1),
IM(1,1,1,1,1,1,1,1,1,1,1,1),
IM(1,1,1,1,1,1,1,1,1,1,1,1)]
@set a 1 aa=9 ll=9
# a is now:
# [
# IM(1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0)
# IM(9.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,9.0)
# IM(1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0)
# IM(1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0)
# IM(1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0)]