struct Foo end
open("/tmp/foo", write=true) do io
write(io, Foo())
end
ERROR: LoadError: MethodError: no method matching write(::IOStream, ::Foo)
Closest candidates are:
write(::IO, ::Any) at io.jl:611
write(::IO, ::Any, ::Any...) at io.jl:612
write(::IOStream, ::UInt8) at iostream.jl:357
...
Stacktrace:
[1] write(::IOStream, ::Foo) at ./io.jl:611
[2] (::var"#5#6")(::IOStream) at
Why doesn’t write(::IOStream, ::Foo) match write(::IO, ::Any)?
write(io::IO, x)
write(filename::AbstractString, x)
Write the canonical binary representation of a value to the given I/O stream or file. Return the number of bytes written into the stream.
See also print to write a text representation (with an encoding that may depend upon io).
Shouldn’t it just call a function like canonical_binary_representation(x) instead of manually raising an error?
I am not sure if such a thing exists. I do believe Julia objects have some options of persistent storage with different trade-offs and none of them is considered canonical.
That’s what I mean too. Instead of implementing write(x), author should implement canonical_binary_representation(x), which write(x) should call. Currently it’s mixing IO with string-building and I don’t see why it should.
If you are concerned with performance and generality, you often will avoid having a function that creates a String object which optionally be called in a write function. The best flow is, in fact, the opposite. You will have a write function that serializes the generic object into an IO object, and if you just want to create a String representation then you will call this write function passing an IOBuffer and extract the String from it after the writeing operation.
Yeah, I agree that explicitly throwing a MethodError is unhelpful, precisely because it creates confusing messages just like this. This is the same problem that replace has, and it’s also confusing: Cannot find overloaded method - #7 by GunnarFarneback