Printing raw string stored in variable

I’m trying to figure out how to print out the contents of a string variable, without it interpreting the characters like \n and \t as newlines and tabs. I want to display the “raw” string such as you would do with ~S(raw \n string \t here), however, I cannot pass a variable or interpolate with that sigil.

Is there an idiomatic way to do this with Elixir?

I think IO.inspect may be what you want:

iex> s = "raw \n string \t here"  
iex> IO.puts s
raw 
 string          here
:ok
iex> IO.inspect s
"raw \n string \t here"

Note that these are not “interpreted”; in the string is the actual character. It is only IO.inspect that is interpreting the string and replacing the actual character with the escape sequence \n and \t.

Apologies, I made a mistake by saying my goal is to “print” the string. I’m writing a function which returns a string, that way the client of my library can print the string wherever they want, or send it to some other I/O mechanism. IO.inspect/1 prints to stdout and returns the string as-is, without escaping. I suppose alternatively, I could add a device argument which defaults to :stdio in favor of the stdlib’s IO.inspect function, and then instead of returning a string I could have my function call IO.inspect/2 and pass the device argument to it.

Or just call Kernel.inspect/2:

iex> inspect(s)
"\"raw \\n string \\t here\""
iex> inspect(s) |>  String.trim("\"") 
"raw \\n string \\t here"

Yes, the leading and trailing part might need to be trimmed if you need. But it seems closer to what you’re after - an escaped string.

3 Likes

Yes!! Kernel.inspect/2 is exactly what I was looking for, thank you! As an elixir rookie, I didn’t know about the Kernel.inspect function–only the IO.inspect, and somehow missed it in the docs.

Can I hijack this thread and ask how you’re supposed to print stuff without them being interpreted as char lists in the output?

Kernel.inspect has options to control this via Inspect.Opts:

• :charlists - when :as_charlists all lists will be printed as char
lists, non-printable elements will be escaped.
When :as_lists all lists will be printed as lists.

When the default :infer, the list will be printed as a charlist if it is
printable, otherwise as list.

As an example:

iex(6)> inspect [32,33,34], charlists: :as_lists
"[32, 33, 34]"
iex(7)> inspect [32,33,34]                      
"' !\"'"

You can tell IEx to default to this behaviour by:

hex> IEx.configure [inspect: [charlists: :as_lists]]
:ok
iex> [32,33,34]                                     
[32, 33, 34]
2 Likes