Structures With Properties

Although properties can be used flexibly with different structures, it may be easier to take advantage of the provided AbstractMetadata type. In the following example we take advantage of the Description and DictExtension. These provide a method of describing a structure and an extensible pool for storing an arbitrary number of properties.

julia> mutable struct MyProperties{M} <: AbstractMetadata{M}
           my_description::String
           my_properties::M
       end

Binding Description and DictExtension to specific fields is accomplished through @assignprops. Several other methods specific to MyProperties are created to provide property like behavior. Most notably, the methods from base overwritten are getproperty, setproperty!, and propertynames.

julia> @properties MyProperties begin
           description(x) => :my_description
           description!(x, val) => :my_description
           Any(x) => :my_properties
           Any!(x, val) => (:my_properties)
       end

julia> m = MyProperties("", Dict{Symbol,Any}())
MyProperties{Dict{Symbol,Any}} with 1 entry
    description:

julia> propertynames(m)
(:description,)
julia> description(m)
""

julia> description!(m, "foo")
MyProperties{Dict{Symbol,Any}} with 1 entry
    description: foo

julia> description(m)
"foo"

julia> m.description = "bar"
"bar"

julia> description(m)
"bar"

julia> m.description
"bar"

Optional properties can be assigned to the DictExtension using the DictExtension(Propert1, Property2) syntax.

julia> @defprop CalibrationMaximum{:calmax}

julia> propdefault(::CalibrationMaximumType, x::AbstractArray) = maximum(x)

julia> proptype(::CalibrationMaximumType, ::Type{<:AbstractArray{T,N}}) where {T,N} = T

julia> @defprop CalibrationMinimum{:calmin}

julia> propdefault(::CalibrationMinimumType, x::AbstractArray) = minimum(x)

julia> proptype(::CalibrationMinimumType, ::Type{<:AbstractArray{T,N}}) where {T,N} = T

julia> struct MyArray{T,N,P<:AbstractArray{T,N},M<:AbstractDict{Symbol,Any}} <: AbstractArray{T,N}
           _parent::P
           my_properties::M
       end

julia> Base.parent(m::MyArray) = getfield(m, :_parent)

julia> Base.size(m::MyArray) = size(parent(m))

julia> Base.maximum(m::MyArray) = maximum(parent(m))

julia> Base.minimum(m::MyArray) = minimum(parent(m))

julia> @assignprops(
           MyArray,
           :my_properties => dictextension(calmax,calmin))