I’d like to define a new type that wraps an existing IO object, for example:
struct MyIOWrapper <: IO
inner::IO
end
Base.write(io::MyIOWrapper, x) =
# custom write logic here
#Base.unsafe_write is also defined
Since Julia doesn’t have a C++ style “base class” mechanism, I’m wondering:
if I define this type as a subtype of IO and implement basic methods like write and unsafe_write, will other built-in functions that operate on IO objects — such as print, println, show — automatically work with my custom type?
In other words, does Julia’s IO interface fully support user-defined subtypes like this?Can user-defined IO subtypes be made fully compatible with all functions that expect an IO?
That is the usual way to do things in julia, yes. However, I don’t think a minimal interface for IO has been specified. It might suffice with defining a write, possible a read. The usual io-functions takes an option io::IO first argument, so whenever they call a write they will use your write.
Thanks! Am I right that there’s no official guideline or minimal required set of methods for a user-defined subtype in Julia — it’s mostly about following the conventions used by Base?
If that’s the case, wouldn’t it be difficult for developers to know which functions should be implemented or extended when defining a new type?
Yes, that’s a recurrent topic. Julia lacks a formal interface/trait mechanism. It’s quite difficult to implement properly without stumbling into problems. Instead it’s common to use “duck-typing” (if it walks like a duck, and talks like a duck, it is a duck). I.e., just add enough low level methods for the things one wants to work.
For some of the abstract types an interface has been defined in the manual, but not for IO: