Tamas, running this
typealias AkoString Union{String, SubString{String}} function parsefield{T <: Real, S <: AkoString}(::Type{T}, str::S) result = T(0) try result = parse(T, str) catch ArgumentError errormsg = string("Failed to parse \"",str,"\" as type ", T) throw(ErrorException(errormsg)) end return result end function parserow(schema, strings) # keep i for reporting column, currently not used [parsefield(T, string) for (i, (T, string)) in enumerate(zip(schema, strings))] end function parsefile(io, schema) line = 1 while !eof(io) strings = split(chomp(readline(io)), ';') parserow(schema, strings) line += 1 # currently not used, use for error reporting end end test_file = """ 1;2;3 4;5;6 7;8;error """ parsefile(IOBuffer(test_file), fill(Int, 3)) by evaluating parsefile(...), results in julia> parsefile(IOBuffer(test_file), fill(Int, 3)) ERROR: Failed to parse "error" as type Int64 in parsefield(::Type{Int64}, ::SubString{String}) at ./REPL[2]:7 in (::##1#2)(::Tuple{Int64,Tuple{DataType,SubString{String}}}) at ./<missing>:0 in collect_to!(::Array{Int64,1}, ::Base.Generator{Enumerate{Base.Zip2{Array{DataType,1},Array{SubString{String},1}}},##1#2}, ::Int64, ::Tuple{Int64,Tuple{Int64,Int64}}) at ./array.jl:340 in collect(::Base.Generator{Enumerate{Base.Zip2{Array{DataType,1},Array{SubString{String},1}}},##1#2}) at ./array.jl:308 in parsefile(::Base.AbstractIOBuffer{Array{UInt8,1}}, ::Array{DataType,1}) at ./REPL[4]:5 On Wednesday, November 2, 2016 at 1:01:30 PM UTC-4, Tamas Papp wrote: > > This is a conceptual question. Consider the following (extremely > stylized, but self-contained) code > > parsefield{T <: Real}(::Type{T}, string) = parse(T, string) > > function parserow(schema, strings) > # keep i for reporting column, currently not used > [parsefield(T, string) for (i, (T, string)) in enumerate(zip(schema, > strings))] > end > > function parsefile(io, schema) > line = 1 > while !eof(io) > strings = split(chomp(readline(io)), ';') > parserow(schema, strings) > line += 1 # currently not used, use for error reporting > end > end > > test_file = """ > 1;2;3 > 4;5;6 > 7;8;error > """ > > parsefile(IOBuffer(test_file), fill(Int, 3)) > > This will fail with an error message > > ERROR: ArgumentError: invalid base 10 digit 'e' in "error" > in tryparse_internal(::Type{Int64}, ::SubString{String}, ::Int64, > ::Int64, ::Int64 > , ::Bool) at ./parse.jl:88 > in parse(::Type{Int64}, ::SubString{String}) at ./parse.jl:152 > in parsefield(::Type{Int64}, ::SubString{String}) at ./REPL[152]:1 > in (::##5#6)(::Tuple{Int64,Tuple{DataType,SubString{String}}}) at > ./<missing>:0 > in collect_to!(::Array{Int64,1}, > ::Base.Generator{Enumerate{Base.Zip2{Array{DataTy > pe,1},Array{SubString{String},1}}},##5#6}, ::Int64, > ::Tuple{Int64,Tuple{Int64,Int64 > }}) at ./array.jl:340 > in > collect(::Base.Generator{Enumerate{Base.Zip2{Array{DataType,1},Array{SubString{ > > > String},1}}},##5#6}) at ./array.jl:308 > in parsefile(::Base.AbstractIOBuffer{Array{UInt8,1}}, > ::Array{DataType,1}) at ./RE > PL[154]:5 > > Instead, I would like to report something like this: > > ERROR: Failed to parse "error" as Int on line 3, column 3. > > What's the idiomatic way of doing this in Julia? My problem is that > parsefield fails without knowing line or column (i in parserow). I could > catch and rethrow, constructing an error object gradually. Or I could > pass line and column numbers to parserow and parsefield for error > reporting, but that seems somehow inelegant (I have seen it in code > though). > > Best, > > Tamas >