https://github.com/joshday/propertyutils.jl
Properties in Julia made easy
https://github.com/joshday/propertyutils.jl
julia utilities
Last synced: 4 months ago
JSON representation
Properties in Julia made easy
- Host: GitHub
- URL: https://github.com/joshday/propertyutils.jl
- Owner: joshday
- License: mit
- Created: 2020-11-03T13:06:46.000Z (over 5 years ago)
- Default Branch: master
- Last Pushed: 2023-06-01T00:10:22.000Z (about 3 years ago)
- Last Synced: 2025-11-01T15:20:49.502Z (8 months ago)
- Topics: julia, utilities
- Language: Julia
- Homepage:
- Size: 23.4 KB
- Stars: 9
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
PropertyUtils
This package lets you:
1. Change `getproperty` to `getfield` via `Fields(x)`
2. Change `getproperty` to `getindex` via `Indexes(x)` (most useful for `AbstractDict{Symbol, Any}`).
3. Similarly, `Fields`, and `Indexes` change the behavior of `setproperty!`.
4. Replace items in an expression with properties from a `src` via `@with src expr`.
5. Join together properties of different objects via `JoinProps`.
## `@with`
### Replace items in an expression with properties from a `src`.
```julia
@with src expr
```
- Every valid identifier `x` in `expr` gets changed to `hasproperty(src, :x) ? src.x : x`
```julia
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:
```julia
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`.
```julia
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`.
```julia
d = Dict(:x => 1, :y => 2)
Indexes(d).y == 2
```
## Composability
`@with`, `Fields`, `Indexes`, and `JoinProps` play nicely together:
```julia
result = @with JoinProps(Fields(A(10)), a, b, Indexes(Dict(:twenty => 20))) begin
x + y + z + twenty
end
result == 36
```
## How this all works with `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.
```julia
Indexes(d).z = 3
d[:z] == 3
```
## Special Thanks
This package borrows ideas from [StatsModels.jl](https://github.com/JuliaStats/StatsModels.jl), [DataFramesMeta.jl](https://github.com/JuliaData/DataFramesMeta.jl), [StaticModules.jl](https://github.com/MasonProtter/StaticModules.jl), and [StatsPlots.jl](https://github.com/JuliaPlots/StatsPlots.jl), which are all fantastic.