I made a dummy range
struct MyRange
starting::Int
ending::Int
end
for which I only care to check whether integers are contained there.
Consequently I implemented the Base.in
function Base.in(r::MyRange, i::Int)
return r.starting <= i <= r.ending
end
Testing the implementation everything works as expected
julia> r = MyRange(4, 7)
MyRange(4, 7)
julia> in(r, 5) # works
true
But if I use the binary operator syntax it errors
julia> 5 in r # errors
ERROR: MethodError: no method matching iterate(::MyRange)
Closest candidates are:
iterate(::Base.AsyncGenerator, ::Base.AsyncGeneratorState)
@ Base asyncmap.jl:362
iterate(::Base.AsyncGenerator)
@ Base asyncmap.jl:362
iterate(::Pkg.Registry.RegistryInstance)
@ Pkg ~/.julia/juliaup/julia-1.10.2+0.x64.linux.gnu/share/julia/stdlib/v1.10/Pkg/src/Registry/registry_instance.jl:
455
...
Stacktrace:
[1] in(x::Int64, itr::MyRange)
@ Base ./operators.jl:1292
[2] top-level scope
@ REPL[32]:1
I get it that I need to implement an iterator for that, but I just donāt want to.
For the sake of completeness the example works if I add the following methods but I find them redundant for my case.
function Base.iterate(r::MyRange)
return (r.starting, 1)
end
function Base.iterate(r::MyRange, i::Int)
i >= r.ending && return nothing
return (r.starting + i, i+1)
end
I really thought that using any binary operator (say Ė£
) as Ė£(a,b)
or a Ė£ b
is indistinguishable. It seems thatās not the case. Is in
a corner case because itās not a commutative operator? But still, I feel that if Base.in(a, b)
is implemented the b in a
should bypass anything else and default to that.