Oops, random click on post. So: function MyType(..) : : fieldvalues = Any[val1,val2,val3] fnames = fieldnames(MyType) for i=1:length(fnames) setfield!(newobj,fname[i],fieldvalues[i]) end return newobj end
On Thursday, October 22, 2015 at 5:52:34 PM UTC+3, Dan wrote: > > the inner constructor, can separate allocation and initialization of a new > object. specifically, first do a: > newobj = new() > then you can set the fields. with a loop this can look like: > fieldvalues = Any[val1,val2,val3] > > > On Thursday, October 22, 2015 at 4:14:51 PM UTC+3, Sloan Lindsey wrote: >> >> I am trying to make some nice inner constructors for an immutable that >> acts as a nice container. I've run into a bit of a problem with using the >> new constructor since I wish to have dynamic construction to avoid having >> to hardcode the hierarchy. >> >> >> #apply new troubles >> >> >> immutable Vec3 >> x::Float64 >> y::Float64 >> z::Float64 >> end >> >> >> immutable Min_Discription >> postion::Array{Vec3} >> valid::Bool >> angry_butter_fly_quotient::Float64 >> end >> >> >> immutable Positive_Vec >> position::Array{Vec3} >> positive::BitArray >> valid::BitArray >> angry_butter_fly_quotient::Array{Float64} >> >> >> function Positive_Vec(elves::Array{Min_Discription}) >> size = length(elves) >> #automagically initialize all the data! >> defaults=((Type{Array{Vec3}},Vec3,null_pos), >> (Type{Array{Int}},Int, -1), >> (Type{BitArray},Bool,false), >> (Type{Array{Float64}},Float64, -Inf)) >> >> >> data_types = [fieldtype(Positive_Vec,x) for x in fieldnames( >> Positive_Vec)] >> declare_list = Array(Any,length(data_types)) >> >> >> for i in 1:length(data_types) >> for (d_type,primitive, default) in defaults >> if d_type == data_types[i] >> if d_type != Type{BitArray} >> declare_list[i] = Array(primitive, size) >> fill!(declare_list[i], default) >> else >> declare_list[i] = BitArray(size) >> fill!(declare_list[i], default) >> end >> end >> end >> end >> #defaults populated. Now overwrite data passed in >> for entry in fieldnames(Min_Discription) >> for (name,index) in enumerate(fieldnames(Positive_Vec)) >> if entry==name >> for (elf,i) in enumerate(elves) >> declare_list[index][i]=elf.(entry) >> end >> end >> end >> end >> #now we worry about a few special cases >> >> >> >> >> for (symbol, index) in enumerate(fieldnames(Positive_Vec)) >> name = string(symbol) >> if name=="positive" # set the size of the structure >> for i in 1:length(elves) >> declare_list[index][i] = elves[i].position.z>0.0 >> end >> end >> end >> return new(declare_list...)#apply(new, declare_list) >> end >> >> >> end >> >> >> a = Min_Discription(Vec3(0.0,0.0,0.0),true,73.27113) >> b = Min_Discription(Vec3(0.0,0.31,1.0),true,892.73165) >> c = Min_Discription(Vec3(0.8364,7.4,500.0),true,4.0) >> >> >> elves = Array(Min_Discription,3) >> elves[1],elves[2],elves[3]= a,b,c >> Positive_Vec(elves) >> >> >> >> julia> include("apply_new_troubles.jl") >> ERROR: LoadError: syntax: ... is not supported inside "new" >> in include at boot.jl:261 >> in include_from_node1 at loading.jl:304 >> >> trying to use apply(new, declare_list) doesn't work either. >> >> I'm being pointed towards making a an expression and doing some macro >> things over here: >> https://github.com/JuliaLang/julia/issues/13700#issuecomment-149861728 >> and the developers actually told me this was a use question so I'm here. >> >> In summary is there a good way to dynamically describe an inner >> constructor in julia? >> >> Presently, I'm thinking of something to emulate the missing splat >> functionality (whether it be interpolation or some @generated code), Or >> even moving the entire generation part into a macro, since all the dynamic >> parts are known at compile time (I simply wish to avoid a wall of hardcoded >> variables that will be difficult to maintain). >> Are there other avenues to follow? I would prefer to keep the functions >> attached to the constructor as this facilitates code clarity. >> >> Any assistance or advice would be appreciated. >> >