Extending println


#1

I’m trying to define my own IO type to prepend a time stamp to each line. What I have so far is:

module Mod1

type DebugFileIO  <: IO
  fstream::IO
end

write(io::DebugFileIO, x::UInt8) = write(io.fstream, x)
flush(io::DebugFileIO) = flush(io.fstream)
close(io::DebugFileIO) = close(io.fstream)


import Base.println

function println(io::DebugFileIO, args...)
  println("args = ", args)
  println(io.fstream, @sprintf("%16e ", 420.0), args...)
end

end

If I run:

julia> using Mod1

julia> println("hello world = ", 42)

It seems like julia gets caught in an infinite loop. When I ^C, this output appears.

This shouldn’t call the method of println defined above, so I’m not sure why this is happening. Oddly, if I remove println("args = ", args), the code works correctly. Also, the failure occurs on julia 0.4 but not 0.5.2. I’m suspicious that adding a println broke it. Is there something wrong with the original code?

Does anyone know a) what might cause this and b) if there are any work-arounds (other than upgrading to 0.5.2, which I can’t do yet because the rest of my code isn’t ready yet).


#2

I don’t know how to answer a), but regarding b) I think you could work around this by extending Base.show instead. I extended it in my code doing something like this:

import Base.show

mutable struct MyType
    x
end

function Base.show(io::IO, n::MyType)
    @printf io "["
    print_with_color(:blue, io, "timestamp goes here")
    @printf io "] "

    print_with_color(:green, io, "put data here, such as MyType.x")
    @printf io " : "
    print_with_color(:bold, io, "$(n.x)\n")

    return
end

When you call println() with MyType values, Base.show will generate the custom output. You can also extend Base.show creating a function for all the types you expect to println(), or a specific extension for each type.


#3

Interesting approach. I’m not sure it will work for my case because I want to change the printing of all types passed to println. My reading of the docs you linked suggests println only calls show sometimes.