The official docs state:
Both concatenation and string interpolation call
string()
to convert objects into string form
However, the following minimum working example seems to demonstrate otherwise:
type MyType
x::Int
end
import Base.string
Base.string(m::MyType) = "world"
m = MyType(4)
println("hello $m")
println("hello " * string(m))
The second last line evaluates to hello MyType(4)
at the REPL, while the last line evaluates (as expected) to hello world
.
So what am I doing wrong?
(I am still on v0.4 but the official doc versions indicate that shouldn't make any difference.)
The documentation is perfectly correct:
julia> expand(:(println("hello $m")))
:(println((Base.string)("hello ",m)))
That is to say, println("hello $m")
is equivalent to println(string("hello", m))
. By the time the code is compiled or interpreted, they are the same thing.
However, your overload
Base.string(m::MyType) = "world"
is not the correct way to overload string
. This method only covers the case with a single argument of type MyType
. (This is why, incidentally, your code seemed to work for concatenation: that particular example involved calling string
on a single argument. The results would have been the same if you had written "$m"
.) The correct way to overload it is
Base.show(io::IO, m::MyType) = print(io, "world")
which may seem weird at first. The reason this must be overloaded is because string
delegates to print
which delegates to show
.
After updating your minimum working example to
type MyType
x::Int
end
Base.show(io::IO, m::MyType) = print(io, "world")
m = MyType(4)
println("hello $m")
println("hello " * string(m))
the result is as expected.
As a footnote, note that your example can be more performantly written as
println("hello ", m)
which avoids the creation of intermediate strings. This illustrates why the system is set up so that string
calls print
which calls show
: the IO method is more generic and can print to various forms of IO directly, whereas if it went the other way around, one would have to convert things into strings (requiring temporary allocation and thus poor performance) before sending to IO.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With