struct Foo end
open("/tmp/foo", write=true) do io
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
 write(::IOStream, ::Foo) at ./io.jl:611
 (::var"#5#6")(::IOStream) at
write(::IOStream, ::Foo) match
Seems like a bug, even
@which agrees with you. It is possible that the method is being called and then explicitly throwing a
julia> struct Foo end
julia> open("/tmp/foo", write=true) do io
@which write(io, Foo())
write(io::IO, x) in Base at io.jl:611
EDIT: yep, this is the code of the function:
write(io::IO, x) = throw(MethodError(write, (io, x)))
I do not find this to be a good pattern, probably
ArgumentError should be used instead. I would do a PR if the devs want to change it.
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.
I am only taking the concept of “canonical binary representation” from the docstring of
I think the docstring means the canonical representation is left to the implementer of the
That’s what I mean too. Instead of implementing
write(x), author should implement
write(x) should call. Currently it’s mixing IO with string-building and I don’t see why it should.
Oh, now I see your point.
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
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