Okay so I wanted to make some quick ways to get data from an array of custom types, but I need some advice to avoid ambiguous method errors.
So I have code that does something like this (note that you need to define at least two methods , so for two different custom element types):
struct MyStruct{T}
value::T
end
function Base.getproperty(vector::Vector{<:MyStruct}, s::Symbol)
if s == :value
return [x.value for x in vector]
elseif s in fieldnames(Vector)
return getfield(vector, s)
else
error("cannot retrieve $s from Vector{<:MyStruct}")
end
end
struct MyOtherStruct{T}
another_value::T
end
function Base.getproperty(vector::Vector{<:MyOtherStruct}, s::Symbol)
if s == :another_value
return [x.another_value for x in vector]
elseif s in fieldnames(Vector)
return getfield(vector, s)
else
error("cannot retrieve $s from Vector{<:MyOtherStruct}")
end
end
I just want this for some syntactic sugar, like:
julia> [MyStruct(5), MyStruct(7)].value
2-element Vector{Int64}:
5
7
I might also want to define this for SubArray and in general just AbstractArray, but let’s just work with Vector as an example for now.
So everything was working fine. But then I got an error with AlgebraOfGraphics v0.10.2, which called into Dictionaries v0.4.5, basically doing this:
using Dictionaries
p = pairs(NamedTuple())
dictionary(p)
This calles into sizehint! with an empty vector, as such:
empty_vector = Vector{Union{}}()
sizehint!(empty_vector , 8)
And now I get ambiguous errors, because sizehint! calls empty_vector.ref. So that’s the minimum working example, just doing getproperty(Vector{Union{}}(), :ref):
ERROR: MethodError: getproperty(::Vector{Union{}}, ::Symbol) is ambiguous.
Candidates:
getproperty(vector::Vector{<:MyOtherStruct}, s::Symbol)
@ Main Untitled-1:19
getproperty(vector::Vector{<:MyStruct}, s::Symbol)
@ Main Untitled-1:10
Possible fix, define
getproperty(::Vector{Union{}}, ::Symbol)
I don’t want to define that method getproperty(::Vector{Union{}}, ::Symbol) in my packages, that would clearly be type piracy.
So I’m wondering if my code is wrong. Or should I just not want to do this? Or should I open an issue on the Julia language github to solve this method ambiguity explicitly?