On Thu, Oct 22, 2015 at 10:55 AM, Dan <getz...@gmail.com> wrote: > 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
This doesn't work for immutables Just to follow up on my mention of @generated in the original issue. Adding a inner constructor like the following (and calling this constructor instead of new) should work (although I also agree it's not a great idea to construct Expr(:new) manually) ``` @generated Positive_Vec(args...) = Expr(:new, Positive_Vec, [:(args[$i]) for i in 1:length(args)]...) ``` Also note that apply(f, args) is always equivalent to f(args...) so you don't need to use it in any case. > > 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.