I want the macro @show but to return a string instead of printing. Does something like that already exist?
Not that I know of, but it would be pretty easy to write this by copying the @show
definition. e.g.
macro showstring(exs...)
args = []
for ex in exs
push!(args, sprint(Base.show_unquoted, ex), " = ", esc(ex), '\n')
end
return :(string($(args...)))
end
Why do you need such a macro? Seems a little odd to me.
You might be interested in the repr
function. It doesn’t have the pretty x = ...
part but that’s easy to do manually and not a difficult macro otherwise.
julia> "x = " * repr(rand(1:10,2,3))
"x = [9 6 3; 8 4 5]"
Thanks. Well, among other things, I thought it might be handy when using @assert. The second argument in @assert isn’t very flexible: it’s just a string, but I’d really like it to automatically show everything in the expression. I didn’t want to replace @assert because in the docs it says: “An assert might be disabled at various optimization levels.” which is a good thing. I suppose I could implement my own mechanism to deactivate my @assert replacement. Actually, that might be ideal.
But, I regularly find myself a bit frustrated with functions that print instead of returning a string… So, maybe what I need is a macro that converts a function that takes an IO as first arg to return a string.
You don’t need a macro for this. That’s exactly what the sprint
function does. Or, at a lower level, you can print to an IOBuffer
and then take!
that to a string — this is how sprint
is implemented.
Thanks! I thought I had just run across something that does that but I couldn’t find it again.
I’m not the OP and this thread is old, but I’ve come here because I want to replace @show . . .
with @info . . . maxlog=1
:
function call_me_many_times()
# . . .
@show array1, array2
end
@show
is more convenient because it shows the names of the variables and its contents in a more compact way than @info
but the above use of @show
can be annoying when the function is called many times while you just want to check the working of your function once. On the other hand, @info
has a nice flag maxlog=1
, so I would use your macro like this:
using Logging
function call_me_many_times()
# . . .
s = @showstring(array1, array2)
@info s maxlog=1
end
It’s a bit strange to me that no means is provided to specify which I/O stream that @show will send the string into. (Compare with the family printf
, sprintf
, and fprintf
in C.)
[Before you point out, I’ve read the thread where the OP asks how to execute only once a section of code within a function. The solutions there are to me a bit overkill just to avoid multiple @show
’s.]
Doesn’t @info "" array1 array2
work for you? It supports all @info
options and prints variable names as well.
Yes and yes. I should’ve highlighted that, in my previous message. Here I quote my words:
[Emphasis is added here.] @info
is verbose:
julia> a = [1,2,3,4]
julia> @show a;
a = [1, 2, 3, 4]
julia> using Logging
julia> @info "" a;
┌ Info:
│ a =
│ 4-element Vector{Int64}:
│ 1
│ 2
│ 3
â”” 4
So, if there is an option to @info
to use a @show
like compact format, then that would be what I’m looking for. (I suppose that with the Logging
package, the destinations of the logs can also be controlled, right?)
That’s just the display of the default ConsoleLogger; you can fully customize logging and set your logger to display the information however you like (with some work), and to send the info wherever you like (to the repl, to a file, over the network, etc). See the JuliaLogging website for an overview: https://julialogging.github.io/