On today's Advent of Code I needed to parse strings into integers. The function I wrote for that was
function fd(s::String, fromto::UnitRange)::Bool
try
parse(UInt, s) in fromto
catch ArgumentError
false
end
end
That function was called several times within an isvalid which was called for all inputs to count the number of valid things.
The result was always 0 and the respective tests kept failing. Then I extracted one of the failing test things and debugged into isvalid, it passed!
I rearraged a few things and tested more, the same thing kept happening:
- Running the code regularly,
fdnever returnedtrue. - When stepping through, I got
truewhere expected.
After replacing the parse to
function fd(s::String, fromto::UnitRange)::Bool
parsed = tryparse(UInt, s)
if isnothing(parsed)
false
else
parsed in fromto
end
end
it immediately worked always and the exercise was solved.
Shouldn't these two versions of the function always return the same result? What happened here?
Update1
This was the example that I used:
println("Sample is ", isvalid(Dict(
"hcl" => "#623a2f", # check with regex
"ecl" => "grn", # checked with set
"pid" => "087499704", # check with regex
"hgt" => "74in", # check with regex
"iyr" => "2012", # this was parsed
"eyr" => "2030", # this was parsed
"byr" => "1980", # this was parsed
)))
Update 2
This post only has a subset of the code. If you want to try yourself, you can get the full file at GitHub. I also recorded a video showing the differing behavior with and without debugging.
The thing is demonstrated quite clearly with @assert fd("2010", 2000:2020) == fdt("2010", 2000:2020) failing in one scenario and not in the other.