PropertyUtils.jl

Utilities for working with properties in Julia
Author joshday
Popularity
3 Stars
Updated Last
1 Year Ago
Started In
November 2020

PropertyUtils

This package provides composable utility functions/macros for working with types that have
getproperty methods.

@with

Replace items in an expression with properties from a src.

@with src expr
  • For any Symbol x that appears in expr and hasproperty(src, x), replace x with getproperty(src, x).
z = 3
result = @with (x = 1, y = 2) begin 
    x + y + z
end
result == 6

joinprops

Join sources to create a union of their props.

Example:

a = (x = 1, y = 2)
b = (y = 3, z = 4)

j = joinprops(a, b)

j.x == 1
j.y == 2  # non-unique props are taken from the first argument that has it
j.z == 4

fields

Map getproperty to getfield.

struct A 
    x::Int 
end
Base.getproperty(::A, x::Symbol) = "hello!"

item = A(1)
f_item = fields(a)

item.x == "hello!"
f_item.x == 1

indexes

Map getproperty to getindex.

d = Dict(:x => 1, :y => 2)

indexes(d).y == 2

Composability

@with, fields, indexes, and joinprops play nicely together:

result = @with joinprops(fields(A(10)), a, b, indexes(Dict(:twenty => 20))) begin 
           x + y + z + twenty
       end

result == 36

setproperty!

setproperty!, e.g. thing.x = 1, is supported if the underlying data structure supports mutation.

  • indexes(x): setproperty! --> setindex!
  • fields(x): setproperty! --> setfield!
  • joinprops(x): setproperty! --> setproperty! on the first instance of the prop. You cannot create new props.
indexes(d).z = 3

d[:z] == 3

Special Thanks

This package borrows ideas from StatsModels.jl, DataFramesMeta.jl, StaticModules.jl, and StatsPlots.jl, which are all fantastic.