diff libinterp/corefcn/pr-output.cc @ 22898:9baa19102908

refactor display and disp functions (bug #49794) * pr-output.cc (Fdisp, Ffdisp): Tag with dispatch classes. (Fdisplay): New function. * ov-class.cc (octave_class::print_with_name): Simply call octave_base_value::print_with_name. * ov-classdef.cc (octave_classdef::print): Simply call print_raw. (octave_classdef::print_with_name): Simply call octave_base_value::print_with_name. * variables.cc (bind_ans): Call display function to print result. * pt-assign.cc (tree_simple_assignment::rvalue1, tree_multi_assignment::rvalue): Likewise. * pt-id.cc (tree_identifier::rvalue): Likewise. * display.m: Delete. * scripts/general/module.mk: Update.
author John W. Eaton <jwe@octave.org>
date Fri, 16 Dec 2016 00:10:27 -0500
parents f84aa17075d4
children b28801182c08
line wrap: on
line diff
--- a/libinterp/corefcn/pr-output.cc	Thu Dec 15 22:04:11 2016 -0500
+++ b/libinterp/corefcn/pr-output.cc	Fri Dec 16 00:10:27 2016 -0500
@@ -53,6 +53,7 @@
 #include "oct-stream.h"
 #include "octave-preserve-stream-state.h"
 #include "pager.h"
+#include "parse.h"
 #include "pr-output.h"
 #include "sysdep.h"
 #include "unwind-prot.h"
@@ -3483,6 +3484,7 @@
 }
 
 DEFUN (disp, args, nargout,
+       classes: cell char double function_handle int8 int16 int32 int64 logical single struct uint8 uint16 uint32 uint64
        doc: /* -*- texinfo -*-
 @deftypefn {} {} disp (@var{x})
 Display the value of @var{x}.
@@ -3526,6 +3528,7 @@
 }
 
 DEFUN (fdisp, args, ,
+       classes: cell char double function_handle int8 int16 int32 int64 logical single struct uint8 uint16 uint32 uint64
        doc: /* -*- texinfo -*-
 @deftypefn {} {} fdisp (@var{fid}, @var{x})
 Display the value of @var{x} on the stream @var{fid}.
@@ -3592,6 +3595,82 @@
 %! endfor
 */
 
+DEFUN (display, args, ,
+       classes: cell char double function_handle int8 int16 int32 int64 logical single struct uint8 uint16 uint32 uint64
+       doc: /* -*- texinfo -*-
+@deftypefn {} {} display (@var{obj})
+Display the contents of the object @var{obj}.
+
+The Octave interpreter calls the @code{display} function whenever it needs
+to present a class on-screen.  Typically, this would be a statement which
+does not end in a semicolon to suppress output.  For example:
+
+@example
+myobj = myclass (@dots{})
+@end example
+
+User-defined classes should overload the @code{display} method so that
+something useful is printed for a class object.  Otherwise, Octave will
+report only that the object is an instance of its class.
+
+@example
+@group
+myobj = myclass (@dots{})
+  @result{} myobj = <class myclass>
+@end group
+@end example
+
+@seealso{class, subsref, subsasgn}
+@end deftypefn */)
+{
+  int nargin = args.length ();
+
+  if (nargin < 1 || nargin > 2)
+    print_usage ();
+
+  std::string name;
+
+  if (nargin == 2)
+    name = args(1).xstring_value ("CALLER must be a string");
+  else
+    {
+      string_vector names = args.name_tags ();
+      std::string tmp = names(0);
+      name = valid_identifier (tmp) ? tmp : "ans";
+    }
+
+  // Only reason we got here is that there was no overloaded display
+  // function.  Rely on built-in functions to display whatever obj is.
+
+  octave_value value = args(0);
+  bool is_scalar = value.is_scalar_type ();
+
+  octave_stdout << name << (is_scalar ? " = " : " =\n\n");
+
+  // Use feval so that dispatch will also work for disp.
+
+  feval ("disp", ovl (value));
+
+  if (! is_scalar)
+    octave_stdout << std::endl;
+
+  return ovl ();
+}
+
+/*
+%!test
+%! str = evalc ("x = 1.1; display (x)");
+%! assert (str, "x =  1.1000\n");
+
+%!test
+%! str = evalc ("display (1.1)");
+%! assert (str, " 1.1000\n");
+
+## Test input validation
+%!error display ()
+%!error display (1,2)
+*/
+
 static void
 init_format_state (void)
 {