GLee
GLee

Reputation: 5093

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

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.

Upvotes: 2

Views: 1834

Answers (2)

ahnlabb
ahnlabb

Reputation: 2162

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.

Upvotes: 2

phyatt
phyatt

Reputation: 19122

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();

Upvotes: 1

Related Questions