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.
>