Search code examples
juliaencapsulation

How can I access variables in nested structures the same way as unnested variables in Julia?


I am new to Julia, so I am sorry if this is an obvious or easy question. I tried googling it, but could not find a good solution.

In Julia, there is no inheritence. My solution to this is to have structures encapsulating structures. E.g.:

mutable struct A
    Var1::Int64
end

mutable struct B
    StructA::A
    Var2::Int64
end

MyA = A(1)
MyB = B(MyA, 2)

Now, when I want to get Var2, I just do:

MyB.Var2
>2

To get Var1, I can do:

MyB.StructA.Var1
>1

Or I can do:

Var1(x::B) = x.StructA.Var1
Var1(MyB)
>1

But now for my question, can I also (re)define a function such that I can do this?:

MyB.Var1
>1

I tried just typing the access to Var1, hoping that the function I defined above would automatically be extended to this use. But I got the expected error:

MyB.Var1
ERROR: type B has no field Var1

I also tried defining the function myself:

x::B.Var1 = x.StructA.Var1
ERROR: type DataType has no field Var1

(x::B).Var1 = x.StructA.Var1
ERROR: UndefVarError: x not defined

These errors do not surprise me. But I do not know how to get what I want, if it is at all possible.

Thanks in advance!


Solution

  • Yes, this is possible by extending getproperty for your type:

    function Base.getproperty(b::B, s::Symbol)
        if s == :Var1
            return b.StructA.Var1
        else
            return getfield(b, s)
        end
    end
    

    Now you can just write:

    julia> MyB.Var1
    1
    

    More info here: https://docs.julialang.org/en/v1/base/base/#Base.getproperty

    There is also a corresponding setproperty! function for modifying fields.