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:
That is to say,
println("hello $m")
is equivalent toprintln(string("hello", m))
. By the time the code is compiled or interpreted, they are the same thing.However, your overload
is not the correct way to overload
string
. This method only covers the case with a single argument of typeMyType
. (This is why, incidentally, your code seemed to work for concatenation: that particular example involved callingstring
on a single argument. The results would have been the same if you had written"$m"
.) The correct way to overload it iswhich may seem weird at first. The reason this must be overloaded is because
string
delegates toprint
which delegates toshow
.After updating your minimum working example to
the result is as expected.
As a footnote, note that your example can be more performantly written as
which avoids the creation of intermediate strings. This illustrates why the system is set up so that
string
callsprint
which callsshow
: 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.