# Write method for object

**URL:** <https://discourse.julialang.org/t/write-method-for-object/62915>\
**Category:** New to Julia\
**Created:** [June 14, 2021, 9:46pm UTC](https://discourse.julialang.org/t/write-method-for-object/62915 "2021-06-14T21:46:44Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![jzr](https://avatars.discourse-cdn.com/v4/letter/j/eb9ed0/32.png) [@jzr](https://discourse.julialang.org/u/jzr)\
**Post date:** [June 14, 2021, 9:46pm UTC](https://discourse.julialang.org/t/write-method-for-object/62915/1 "2021-06-14T21:46:44Z")

</div>

```julia
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)`?

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [June 14, 2021, 10:00pm UTC](https://discourse.julialang.org/t/write-method-for-object/62915/2 "2021-06-14T22:00:53Z")

</div>

Seems like a bug, even `@which` agrees with you. It is possible that the method is being called and then explicitly throwing a `MethodError` exception.

```julia
julia> struct Foo end

julia> open("/tmp/foo", write=true) do io
           @which write(io, Foo())
       end
write(io::IO, x) in Base at io.jl:611

```

EDIT: yep, this is the code of the function:

```julia
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.

---

<div class="post-metadata">

**Author:** ![jzr](https://avatars.discourse-cdn.com/v4/letter/j/eb9ed0/32.png) [@jzr](https://discourse.julialang.org/u/jzr)\
**Post date:** [June 14, 2021, 10:08pm UTC](https://discourse.julialang.org/t/write-method-for-object/62915/3 "2021-06-14T22:08:11Z")

</div>

```julia

  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?

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [June 14, 2021, 11:28pm UTC](https://discourse.julialang.org/t/write-method-for-object/62915/4 "2021-06-14T23:28:26Z")

</div>

> [@jzr](#):
>
> Shouldn’t it just call a function like `canonical_binary_representation(x)`

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.

---

<div class="post-metadata">

**Author:** ![jzr](https://avatars.discourse-cdn.com/v4/letter/j/eb9ed0/32.png) [@jzr](https://discourse.julialang.org/u/jzr)\
**Post date:** [June 14, 2021, 11:33pm UTC](https://discourse.julialang.org/t/write-method-for-object/62915/5 "2021-06-14T23:33:53Z")

</div>

> [@Henrique\_Becker](#):
>
> none of them is considered canonical.

I am only taking the concept of “canonical binary representation” from the docstring of `write`.

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [June 14, 2021, 11:52pm UTC](https://discourse.julialang.org/t/write-method-for-object/62915/6 "2021-06-14T23:52:45Z")

</div>

I think the docstring means the canonical representation is left to the implementer of the `struct`.

---

<div class="post-metadata">

**Author:** ![jzr](https://avatars.discourse-cdn.com/v4/letter/j/eb9ed0/32.png) [@jzr](https://discourse.julialang.org/u/jzr)\
**Post date:** [June 14, 2021, 11:54pm UTC](https://discourse.julialang.org/t/write-method-for-object/62915/7 "2021-06-14T23:54:02Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [June 15, 2021, 1:20am UTC](https://discourse.julialang.org/t/write-method-for-object/62915/8 "2021-06-15T01:20:10Z")

</div>

Oh, now I see your point.

> [@jzr](#):
>
> 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 `write`ing operation.

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [June 15, 2021, 2:15am UTC](https://discourse.julialang.org/t/write-method-for-object/62915/9 "2021-06-15T02:15:49Z")

</div>

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](https://discourse.julialang.org/t/cannot-find-overloaded-method/48633/7)
