I like the syntax of properties, like that they’re not the same as fields, and that I don’t have to export them. I’m considering switching from using accessor functions to properties in a large chunk of code, but I’m not sure it’s a good idea.
Suppose I have struct S end
.
-
Is it okay to use underscores as property names?
S()._
is currently valid syntax. -
Should we be allowed to define properties for
Type{S}
? This would be useful in, for example, accessing parameters in parametric types (likeArray{Int64, 2}.dims
). Currently, I can defineS._
by overwritingBase.getproperty
. The issue is, types already come with these property names(:name, :super, :parameters, :types, :instance, :layout, :hash, :flags)
and I don’t know that it’s gaurenteed that they will not change in the future. I don’t think I can redefineBase.getproperty
from inside another funtion, so I would need a macro? I’d need to make sure that the existing names don’t conflict the user-defined names. But then also make sure that I’m able to update the definition of properties that I myself defined. -
What if I redefine
S.name
? -
If I should be allowed to define properties of types (
S._
), what’s a good way to updateBase.propertynames
? -
What happens if I don’t update
propertynames
? I figure it’s a good way to keep track of what properties a type or its subtypes is supposed to implement. Which brings me to: -
What’s a good way to verify that a list of properties have been implemented for a type? This is my current approach:
Base.getproperty(s::S, name::Symbol) = getproperty(s, Val(name)) # dispatch on Val{name}
Base.getproperty(s, ::Val{name}) where {name} = Base.getfield(s, name) # default: pass to getfield
Base.getproperty(s, ::Val{:_}) = "underscore" # define property
hasmethod(getproperty, Tuple{S, Val{:_}}) # verify: do this for all properties
- What are other things to consider when choosing between (accessor) functions and properties?