Is there a direct way to get the string of the output of `show`?

I need to write the following script:

# typeof
# 値の型を得る

function print_typeof(x)
    print("表現「")
    show(x)
    println("」の値の型は「", typeof(x), "」である。")
end

print_typeof(true)
print_typeof(1)
print_typeof(1.0)
print_typeof('1')
print_typeof("1")

to get the following result:

表現「true」の値の型は「Bool」である。
表現「1」の値の型は「Int64」である。
表現「1.0」の値の型は「Float64」である。
表現「'1'」の値の型は「Char」である。
表現「"1"」の値の型は「String」である。

I want to write it more simple but show doesn’t accept multiple arguments.

# impossible
show(a, b, c, d, e, f, g)
# possible
print(a, b, c, d, e, f, g)

So I need to define the following function to use print.

function showstring(x)
    io = IOBuffer()
    show(io, x)
    result = String(take!(io))
    close(io)
    result
end

print(a, b, showstring(c), d, e, showstring(g))

By this, I can write print_typeof as

print_typeof(x) = println("表現「", showstring(x), "」の値の型は「", typeof(x), "」である。")

or

sentence_typeof(x) = "表現「$(showstring(x))」の値の型は「$(typeof(x))」である。"
const print_typeof = println ∘ sentence_typeof

Is there another way to shorten the definition of my print_typeof or showstring?

Or, should I define showmultiple?

showmultiple(xs...) = foreach(show, xs)

I think you can replace showstring(x) by sprint(show, x).

1 Like

repr(x) is the same as sprint(show, x)

4 Likes

I’m confused about many things here.

  1. You say show doesn’t accept multiple arguments, but that’s what print/println is for.

  2. Why does print_typeof have a separate show step? print/println calls show internally, so println("表現「", x, "」の値の型は「", typeof(x), "」である。") does the same thing AFAIK. Concatenation and string interpolation call string internally, which also internally calls print and thus show, so "表現「$x」の値の型は「$(typeof(x))」である。" also does the same thing. print only deviates from show for formatting features, like removing the quotes from printed strings.

  3. Why make showstring when the docstring for show already says repr gives its output as a String?

1 Like

For 2., print("hello") and show("hello") give different results. It is necessary to distinguish between them for my purpose.

That’s what the last sentence of 2. means

For 3., I overlooked that the show docstring mentions repr and I haven’t used it.

I suppose that you want following functionality provided most easily by the IOCapture package:

using IOCapture
function print_typeof(x)
	c = IOCapture.capture() do; show(x) end
	println("表現「", c.output, "」の値の型は「", typeof(x), "」である。")
end

Alternatively you can use the Suppressor package:

#using IOCapture
using Suppressor
function print_typeof(x)
	#c = IOCapture.capture() do; show(x) end
	#println("表現「", c.output, "」の値の型は「", typeof(x), "」である。")
	strOfStdOut = @capture_out show(x)
	println("表現「", strOfStdOut, "」の値の型は「", typeof(x), "」である。")
end

For the sake of completeness below an approach ( mentioned by oxinabox in post #3 ) which in the simple case of a show() function delivers the required result without the need of usage of any package:

#using IOCapture
#using Suppressor
function print_typeof(x)
	#c = IOCapture.capture() do; show(x) end
	#println("表現「", c.output, "」の値の型は「", typeof(x), "」である。")
	#strOfStdOut = @capture_out show(x)
	typeOf = typeof(x)
	#println("reprOfValue「$strOfStdOut」typeOfValue 「$typeOf」")
	reprOf = repr(x)
	println("reprOfValue「$reprOf」typeOfValue 「$typeOf」")

end

Indeed, it seems that these packages and methods can achieve the goal, but they are overkill for my purposes. In any case, thank you for telling me methods I didn’t know about.