Defining custom getindex method

Hi all, just started learning Julia, and I think I’m missing something really obvious here. I’m trying to make a type indexable, but I get an error when using the [ …] syntax. Specifically, if g is an instance of my type, getindex(g,1) works fine, but g[1] gives me an error. The getindex I’ve defined seems like it should be suitably general to match this type, and this is especially weird to me because the documentation says that g[1] should be compiled as getindex(g,1). Example:

struct Graded{S,T}
    summands :: Dict{S,T}

function getindex(x::Graded{S,T}, k::S) where {S,T}
    return x.summands[k]

d = Dict{Int,Array{Int}}([0=>[], 1=>[1,2,3], 2=>[10,11,12]])
g = Graded{Int,Array{Int}}(d)


The last line gives the error:

 ERROR: LoadError: MethodError: no method matching getindex(::Graded{Int64,Array{Int64,N} where N}, ::Int64)

The problem here is that g[1] always calls Base.getindex, while your function definition has in fact made a new function in your current module. The solution is to always qualify functions you are trying to extend, when the original definition is in another module:

julia> @which getindex

julia> methods(getindex)  # just one:
# 1 method for generic function "getindex":
[1] getindex(x::Graded{S, T}, k::S) where {S, T} in Main at REPL[523]:1

julia> methods(Base.getindex) |> length

julia> function Base.getindex(x::Graded{S,T}, k::S) where {S,T}
           return x.summands[k]

julia> print(g[1])
[1, 2, 3]

It’s a little strange to think that you could mean anything else. But the general rule makes more sense – for instance it lets you use words like sum or sign as variable names within a function, so long as you assign to them before reading from them, without worrying that these also exist as functions exported by Base.


Perfect, thank you!