Recommended approach for getproperty shadowing

Suppose I have a wrapper type that has some contents I would like to index with symbols, for both getindex and getproperty syntaxes (if you want a concrete example, think of a DataFrame).

However, this could be problematic when the symbol names coincide with the field name.

What’s the recommended way of dealing with this? Eg fall back to getfield for the fields, perhaps making this more convenient with an accessor? Eg

struct Foo{T <: NamedTuple}
    contents::T
end

contents(f::Foo) = getfield(f, :contents)

Base.getproperty(f::Foo, name::Symbol) = getproperty(contents(f), name)
Base.propertynames(f::Foo) = propertynames(contents(f))

then

julia> f = Foo((a = 1, b = 2, contents = 3))
Foo{NamedTuple{(:a, :b, :contents),Tuple{Int64,Int64,Int64}}}((a = 1, b = 2, contents = 3))

julia> f.a
1

julia> f.b
2

julia> f.contents
3

In Gtk.jl for GObjects we return the field if it exists otherwise we return the Gtk property. I haven’t used it much but it seems to work fine in practice. That said in Gtk you also need to specify the type of the property you want to access, so it’s clear syntactically if the intent is to access a field or a property (otherwise it would be a bit awkward):

foo.bar #field
foo.bar[Int] #Gtk property of type Int
1 Like
struct Foo{T <: NamedTuple}
    asdfasdfasdfwqefasdfvjwlqewazdf::T
end

Problem solved.

1 Like

@Tamas_Papp FWIW, PyCall.jl is planning to add the interface implemented as in your example code (i.e., property lookup is completely forwarded and field lookup is done by a custom accessor wrapping getfield).

1 Like