Just for the sake of it. This is what has gone into my runtests.jl
for checking whether two structs are the same (or nearly the same if they have Floats). It’s ugly, doesn’t cover all types, but it only takes a few μs to run. (You don’t need to initialize test
outside the function anymore.
function chkFieldNames!(x::S, y::T, icount=0, depth=0; test::Vector{Bool} = Vector{Bool}(undef,0), max_call=50) where {S, T}
atol = 1e-5 # Resisted temptation to make an argument that is recursively passed around.
if icount == 0 && depth == 0
global test = Vector{Bool}(undef,0)
println("Test initialised")
end
tx = typeof(x)
ty = typeof(y)
if tx == ty && depth < max_call
for i in fieldnames(tx)
gx = getfield(x, i)
gy = getfield(y, i)
tgx = typeof(gx)
if isprimitivetype(tgx)
#println("Primitive type: ", tgx)
if tgx <: AbstractFloat
push!(test, isapprox(gx, gy, atol=atol))
else
push!(test, gx == gy)
end
elseif tgx <: AbstractArray
#println("AbstractArray type: ", tgx)
if ndims(gx) == ndims(gy)
push!(test, isapprox(gx, gy, atol=atol))
else
push!(test, 0)
end
elseif tgx <: String
#println("String type: ", tgx)
push!(test, gx == gy)
else
depth += 1
#icount != 0 || depth == 1 && println("Non-primitive type: ", tgx)
chkFieldNames!(gx, gy, icount, depth, test=test)
end
end
else
if depth >= max_call
@warn "Run-away search -- self referential types?"
return test
else μ
println("Unequal types: ", tx, " and ", ty)
push!(test, 0)
end
end
icount += length(test)
#icount != 0 && println("Count = ", icount)
return test
end