What is the equivalent of Matlab's default display function which outputs to a file instead of stdout?

io, matlab

Solution

What you want to do is find a generic string conversion that looks like `display()`, use that to build your output as strings, and then you can pass it to `fprintf()` or other normal output functions.

The Matlab output produced by omitting the semicolon is done by calling `display()` on the result of the expression. Matlab provides a `display` implementation for all the builtin types and a fallback implementation for user-supplied objects. The `disp()` function displays the value in the same way, but omits the variable name.

This is basically the equivalent of Java's `toString` function which is getting called behind the scenes when you print arbitrary objects to a `PrintStream`. The display functionality is mostly not in `PrintStream` itself, but in the polymorphic `toString` method that knows how to convert objects to display strings. The difference is that Java `toString` returns a String data value, which is easy to work with programmatically and compose with other operations, so you can manipulate it send it where you want, but Matlab's `display` and `disp` always output to stdout instead of giving you a string back.

What you want is probably something that will give you `display`-style output as a string, and then you can output it where you want, using `fprintf()` or another string output function.

One easy approach is to use `evalc()` to just call `display` and capture the output. The `evalc` function lets you run arbitrary Matlab code, and capture the output that would have gone to `stdout` to a `char` variable instead. You can make a generic conversion function and apply it to any values you want.

function out = tostr(x)
    out = evalc('disp(x)');
end

The other option is to define a new `dispstr()` function, write it to convert Matlab built-in types (maybe using the `evalc` technique), and override `dispstr` in the objects you write, and call it polymorphically. More work, but it could end up being cleaner and faster, because `evalc` is slow and sometimes fragile. Also have a look at `mat2str` for ideas on an alternate output mechanism.

Then you'd be able to output values generically, without specifying the type, with calls like this. Note that in the second form, the placeholders are all just `%s` regardless of the type of object.

function displaySomeArbitraryDataValues(fh, foo, bar, baz)
% fh is a file handle previously opened with fopen()
fprintf(fh, 'foo=%s, bar=%s and baz=%s', tostr(foo), tostr(baz), tostr(qux))
end

Matlab does not have an formatted output function that automatically calls a display conversion, so you'll have to call the conversions explicitly in a lot of cases, so it'll be a little more wordy than Java. (Unless you want to go all out and write your own polymorphic auto-converting output functions or string wrapper objects.) If you want to use placeholders, it's easy enough by forcing all the args to be converted.

function out = sprintf2(format, varargin)
%SPRINTF2 A sprintf equivalent with polymorphic input conversion
% Use '%s' placeholders for everything in format, regardless of arg type
args = varargin;
strs = {}
for i = 1:numel(args)
    strs{i} = tostr(args{i});
end
out = sprintf(format, strs{:});
end

If you want to get fancy, you could do mixed `printf` conversions by parsing the `printf` format argument yourself, defining a new placeholder like `%y` that calls your `tostr()` on the argument and then prints that string (probably by replacing the placeholder with `%s` and the argument with the `tostr()` result), and passes all the normal placeholders along to `printf` with un-converted arguments. This is kind of difficult to implement and can be computationally expensive, though.

You could make it behave more like Java by providing `char` conversions that convert object values to display strings, but that's inconsistent with how Matlab's existing numeric to `char` conversions work, so it wouldn't be fully generic, and you would run in to some odd edge cases, so I wouldn't recommend that. You could do a safer form of this by defining a new `@string` class that wraps `char` strings, but does implicit conversions by calling your `tostr()` instead of `char()`. This could be a big performance hit, though, because Matlab OOP objects are substantially slower than operations with built-in types and plain functions.

For background: basically, the reason you need to pass explicit conversions to `fprintf` in Matlab, but you don't need to with the `PrintStream` stuff in Java is that `fprintf` is inherited from C, which did not have run time type detection, especially of varargs, in the language. Matlab does, so `fprintf` is more limited than it needs to be. However, what `fprintf` does give you is fine-grained control over the formatting of numeric values and a concise calling form. These are useful, as evidenced by how Java programmers complained for years about not having them in Java and eventually got them added. It's just that Matlab sticks to the C-supported fprintf conversions, where they could easily add a couple new generic conversions that examine the type of the input at runtime and give you the generic output support you want.

Problem

I apologize if this question is badly named, but let me explain through a simple analogy to Java. Please note, this question is about Matlab, not Java. In Java, the standard way to write to the `stdout` stream is to say `System.out.println`. If we want to print this exact output to a file, we can create a `PrintStream` object `myPrinter`, point it at a file, and replace the call to `System.out.println` with the call to `myPrinter.println`. ``` System.out.println("Hello World"); PrintStream myPrinter = new PrintStream(new File("MyJournal.log")); myPrinter.println("Hello Log"); ``` In Matlab, one standard way to write to standard out is to write an expression, variable or statement without a following semicolon. How would I rewrite my Matlab statements to get this (ascii) output into a file instead? I would like to avoid solutions that redirect `stdout` to a file, because I still want some things printed to the console. Additionally, I do not want to have to specify the type of the object that is being written to file, because the standard way does not require type specification. Update: In particular, as far as I know, the `printf` family of functions requires type specification (different format string depending on the type of object). I am trying to avoid this because I seek a more generic solution.

Original source