# Nested getproperty requests

**URL:** https://discourse.julialang.org/t/nested-getproperty-requests/27968
**Category:** Internals & Design
**Created:** [August 25, 2019, 8:18pm UTC](https://discourse.julialang.org/t/nested-getproperty-requests/27968 "2019-08-25T20:18:25Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![ablaom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ablaom/32/4889_2.png) [@ablaom](https://discourse.julialang.org/u/ablaom)
#### Post date: [August 25, 2019, 8:18pm UTC](https://discourse.julialang.org/t/nested-getproperty-requests/27968/1 "2019-08-25T20:18:25Z")

</div>

I have a use for accessing and setting _nested_ properties of julia objects. To achieve this, I have the code below in a package. I have been reasonably accused of type piracy and wondered: (i) if others agree this is dangerous to implement, and (ii) whether julia language developers might conceivably view it as an extension to the language:

```julia
"""
    getproperty(object, nested_name::Expr)

Call getproperty recursively on `object` to extract the value of some
nested property, as in the following example:

    julia> object = (X = (x = 1, y = 2), Y = 3)
    julia> getproperty(object, :(X.y))
    2

"""
function Base.getproperty(obj, ex::Expr)
    subex, field = reduce_nested_field(ex)
    return getproperty(getproperty(obj, subex), field)
end

"""
    setproperty!(object, nested_name::Expr, value)

Set a nested property of an `object` to `value`, as in the following example:

    julia> mutable struct Foo
               X
               Y
           end

    julia> mutable struct Bar
               x
               y
           end

    julia> object = Foo(Bar(1, 2), 3)
    Foo(Bar(1, 2), 3)

    julia> setproperty!(object, :(X.y), 42)
    42

    julia> object 
    Foo(Bar(1, 42), 3)

"""
function Base.setproperty!(obj, ex::Expr, value)
    subex, field = reduce_nested_field(ex)
    last_obj = getproperty(obj, subex)
    return setproperty!(last_obj, field, value)
end

# applying the following to `:(a.b.c)` returns `(:(a.b), :c)`
function reduce_nested_field(ex)
    ex.head == :. || throw(ArgumentError)
    tail = ex.args[2]
    tail isa QuoteNode || throw(ArgumentError)
    field = tail.value
    field isa Symbol || throw(ArgmentError)
    subex = ex.args[1]
    return (subex, field)
end

```

---

<div class="post-metadata">

### Author: ![tkf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkf/32/17635_2.png) [@tkf](https://discourse.julialang.org/u/tkf)
#### Post date: [August 25, 2019, 8:39pm UTC](https://discourse.julialang.org/t/nested-getproperty-requests/27968/2 "2019-08-25T20:39:14Z")

</div>

I highly recommend looking at [Setfield.jl](https://jw3126.github.io/Setfield.jl/latest/intro/) which is implemented based on very elegant and simple [lens API](https://jw3126.github.io/Setfield.jl/latest/#Setfield.Lens). Its primary focus is on the immutable data structures at this point but it should not be difficult to extend to in-place operations. Discussion on the support for mutable data structure is happening in [https://github.com/jw3126/Setfield.jl/issues/32](https://github.com/jw3126/Setfield.jl/issues/32)

---

<div class="post-metadata">

### Author: ![mauro3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mauro3/32/292_2.png) [@mauro3](https://discourse.julialang.org/u/mauro3)
#### Post date: [August 26, 2019, 6:39am UTC](https://discourse.julialang.org/t/nested-getproperty-requests/27968/3 "2019-08-26T06:39:47Z")

</div>

Maybe of interest [JuliaCon 2018 | Interacting with nested data | Andy Ferris - YouTube](https://youtu.be/vWZzmV7mHiw)
