I’m doing doing exercises on exercism.org to get familiar with Julia (most of my experience is in Python, C++, or Java). For one exercise I’ve made a custom Clock type, and I want to overload Base.show to print a timestring field, and overload + and - to operate on the actual time value like so:
struct Clock{Time}
time::Time
timestring::AbstractString
function Clock(hours::Int64, minutes::Int64)
delta_hours = div(minutes, 60)
delta_minutes = delta_hours * 60
hours += delta_hours
minutes -= delta_minutes
if hours < 0
hours %= 24
hours += 24
end
if minutes < 0
hours -= 1
hours %= 24
minutes += 60
end
minutes %= 60
hours %= 24
time = Time(Hour(hours), Minute(minutes))
timestring = Dates.format(time, "HH:MM")
end
end
Base.:(+)(c::Clock, m::Dates.Minute) = getfield(c, time) + m
Base.:(+)(c::Clock, h::Dates.Hour) = getfield(c, time) + h
Base.:(-)(c::Clock, m::Dates.Minute) = getfield(c, time) - m
Base.:(-)(c::Clock, h::Dates.Hour) = getfield(c, time) - h;
Base.:(-)(m::Dates.Minute, c::Clock) = m - getfield(c, time) + m
Base.:(-)(h::Dates.Hour, c::Clock) = m - getfield(c, time) + h
Base.show(io::IO, c::Clock{Time}) = print(io, timestring)
As far as I can tell from the docs, this should do what I’m wanting, but when I attempt, for example,
Clock(10, 0) + Dates.Minute(3) == Clock(10, 3)
I get the following error:
MethodError: no method matching +(::String, ::Dates.Minute)
Closest candidates are:
+(::Any, ::Any, !Matched::Any, !Matched::Any...) at operators.jl:591
+(!Matched::ExercismTestReports.Clock, ::Dates.Minute) at ./clock.jl:31
+(!Matched::P, ::P) where P<:Dates.Period at /usr/local/julia/share/julia/stdlib/v1.8/Dates/src/periods.jl:77
This is exactly what I’m trying to address by overloading. Where am I going wrong?
Thanks in advance, and here is the stacktrace from exercism, in case it’s helpful:
Stacktrace:
[1] macro expansion
@ /usr/local/julia/share/julia/stdlib/v1.8/Test/src/Test.jl:464 [inlined]
[2] macro expansion
@ ./runtests.jl:69 [inlined]
[3] macro expansion
@ /usr/local/julia/share/julia/stdlib/v1.8/Test/src/Test.jl:1363 [inlined]
[4] top-level scope
@ ./runtests.jl:69```