Is there a way to suppress outputs inside a function in a Julia Jupyter notebook?

Viewed 770

In a Jupyter cell, I'd like to call a function that has some println, @show, etc in it, but I don't want to see those outputs. Is there a way to call a function while suppressing outputs? I'm aware of ;, but my understanding is that ; only affects the return value.

For example, let's say you have a function

function testOutputs()
    @show("Show macro still showing")
    println("Println still showing")
    a = 1 + 2
end

Calling testOutputs(); in a cell results in:

"Show macro still showing" = "Show macro still showing"
Println still showing

I would like it to print nothing.

2 Answers

As phyatt's answer highlights it would often be better for library code to use a configurable logging mechanism. However, sometimes you want to call code that, for whatever reason, writes directly to stdout. One way to handle these cases is to use redirect_stdout.

For example:

real_stdout = stdout
(rd, wr) = redirect_stdout();
# Noisy code here
redirect_stdout(real_stdout)

You'd probably want to put this in a function or a macro or simply use Suppressor.jl a library that provides these macros. If you want to capture the output the way the ipython %%capture magic does you can have a look at @capture_out in Suppressor.jl, this SO question and this forum thread.

No one is stopping you from making those functions useless. It warns you that you must import from Base to actually override them.

julia> import Base.println

julia> println(args...) = nothing
println (generic function with 3 methods)

julia> import Base.@show

julia> macro show(args...)
       return :(nothing) # TODO: make this a pass thru instead of a removal
       end
@show (macro with 1 method)

julia> testOutputs()
3

julia> testOutputs();

Occasionally a programmer will put an @show in the middle of an expressions, and this kind of macro override would make it break such lines.

The better alternatives IMHO are to use a logging library like Memento.jl or the baked in Logging of julia. They have single line functions for mass disabling logging thru their mechanisms.

https://docs.julialang.org/en/v1/stdlib/Logging/
https://docs.julialang.org/en/v1/stdlib/Logging/#Logging.disable_logging

julia> @debug "Hello World"

julia> @info "Hello World"
[ Info: Hello World

julia> @warn "Hello World"
┌ Warning: Hello World
└ @ Main REPL[10]:1

julia> @error "Hello World"
┌ Error: Hello World
└ @ Main REPL[11]:1

julia> using Logging

julia> Logging.disable_logging(Logging.Error)
LogLevel(2001)

julia> @debug "Hello World"

julia> @info "Hello World"

julia> @warn "Hello World"

julia> @error "Hello World"

https://invenia.github.io/Memento.jl/latest/

Memento.config!("emergency")

Or without any additional libraries make a global flag at the top of your file called debug_print and swap it when needed.

julia> global debug_print = true
true

julia> function testOutputs()
           debug_print && @show("Show macro still showing")
           debug_print && println("Println still showing")
           a = 1 + 2
       end
testOutputs (generic function with 1 method)

julia> testOutputs();
"Show macro still showing" = "Show macro still showing"
Println still showing

julia> debug_print = false
false

julia> testOutputs();
Related