Overloading `fieldnames()` function

Is it safe to overload the fieldnames() function if I want to hide some fields for a specific type?

Do you want to prevent people from accessing field names from an instance of a type or prevent them from accessing fieldnames from the type itself? If the former, you’ll want to overload propertynames. If the latter, I’d say probably not to do that. I don’t know if it’s actually unsafe, but it makes generic reconstruction (like what @set from Setfield.jl would have to do). And I don’t think it buys you any extra protection from users accessing the field because that will usually be happening through propertynames/getproperty/setproperty! on an instance rather than a type.

First of all, nothing will break if I overload this function?

Things might break, but trying to hide fields with that won’t really work - if you take away the ability to get a field of an object, you yourself also won’t be able to access it.

In general, there is no way to completely hide the internals of an object for the users of your code.

what should i do to skip struct fields during serialization/deserialization?

Write a custom serialization function on a struct-by-struct basis - though for more specific help, you’ll have to give some more information on what you’re trying to do.

1 Like

If I want do deserialize Dict() into struct, but some fields should not be deserialized (they are generated in the constructor based on the rest of the fields)

deserialization function:

function deser(
    ::CustomType,
    ::Type{D},
    data::AbstractDict{K,V},
)::D where {D<:Any,K<:Union{AbstractString,Symbol},V<:Any}
    vals = Union{fieldtypes(D)...}[]

    for (type, name) in zip(fieldtypes(D), fieldnames(D))

        ...

        push!(vals, res)
    end

    return D(vals...)
end

I’d filter the names in that loop by checking whether you “want” them, otherwise continue the loop to process the next value.