Existing methods work fine, in fact, I am building on them. But I find it useful to encapsulate parsing information into an object. Eg “this is a date, parse it like this”, or “parse this field with the following strings treated as missing data”. The type system is not rich enough to describe this.
(EDIT) To make things concrete, this is an example I am using for a dataset at the moment:
immutable CustomDate end
macro nullable_catch(expr, catch_errors=:ArgumentError)
@assert expr.head ≡ :(::) "Use this macro as @nullable_catch value::type."
(expr_value, expr_type) = map(esc, expr.args)
quote
try
Nullable{$expr_type}($expr_value)
catch e
if isa(e, $(esc(catch_errors)))
Nullable{$expr_type}()
else
rethrow()
end
end
end
end
function tryparse(::Type{CustomDate}, string)
if !isascii(string) || (string == "00000000")
Nullable{Date}()
elseif endswith(string, "00") # day is corrected to 1
@nullable_catch Date(string[1:end-2], "yyyymm")::Date
else
@nullable_catch Date(string, "yyyymmdd")::Date
end
end
which I call like this:
tryparse(CustomDate, "19800101")
tryparse(CustomDate, "19800100") # bogus dates in my data
tryparse(CustomDate, "nonsensical") # Nullable{Date}()
The design/style questions are:
- whether I should define methods for
tryparse
anyway, or make a new function, - should I need a function that returns the parsed type for parsing specifications which are not Julia types, eg
parsedtype(::Type{CustomDate}) = Date
with a fallback
parsedtype{T}(::Type{T}) = T
for other types. But maybe that is too general, and I should only define for types which tryparse
accepts? Interfaces are hard