Thread Subject:
semi-colon suppress output of user defined function

Subject: semi-colon suppress output of user defined function

From: Ben

Date: 12 May, 2011 18:42:05

Message: 1 of 16

I have a function that I've written that prints some text to the command window. I'd like to have that text not show up if the function is called with a semi-colon after it:

>> MyFunc()
Hello World!
>>
vs

>> MyFunc();
>>

There are a few threads out there on this issue, but they all found work-arounds that I would rather not use. First, I don't want to add a print/don't print argument. (link: http://www.mathworks.com/matlabcentral/newsreader/view_thread/302540) Second, I don't want the output suppressed in the case where nargout ==0 (link: http://www.mathworks.com/matlabcentral/answers/3662-how-can-i-check-for-semicolon-termination-of-my-own-function).

A possible solution would be to open the history.m file in prefdir, search for the last line of the file, then see if it ends in a semi-colon (link: http://www.mathworks.com/matlabcentral/newsreader/view_thread/236568). However, since I have no way of knowing if that file is up to date or not, I can't use this solution either. (I could change my command history settings to save the file after every command, but MyFunc will be used by people other than me and I don't want it to be setting specific.)

Any ideas?

Subject: semi-colon suppress output of user defined function

From: dpb

Date: 12 May, 2011 18:58:16

Message: 2 of 16

On 5/12/2011 1:42 PM, Ben wrote:
> I have a function that I've written that prints some text to the command
> window. I'd like to have that text not show up if the function is called
> with a semi-colon after it:
>
>>> MyFunc()
> Hello World!
>>>
> vs
>
>>> MyFunc();
>>>
>
> There are a few threads out there on this issue, but they all found
> work-arounds that I would rather not use. ...
...
> Any ideas?

Yeah, dream on...

How is the function supposed to know to do something based on an
indication that isn't even made apparent to it???

In short, pick one of the workarounds and run w/ it or make up another
on your own (a global flag variable set/cleared in the calling examined
in the function would be another kludge).

--

Subject: semi-colon suppress output of user defined function

From: Ben

Date: 12 May, 2011 19:49:05

Message: 3 of 16

dpb <none@non.net> wrote in message <iqhak9$rer$1@speranza.aioe.org>...
> On 5/12/2011 1:42 PM, Ben wrote:
> > I have a function that I've written that prints some text to the command
> > window. I'd like to have that text not show up if the function is called
> > with a semi-colon after it:
> >
> >>> MyFunc()
> > Hello World!
> >>>
> > vs
> >
> >>> MyFunc();
> >>>
> >
> > There are a few threads out there on this issue, but they all found
> > work-arounds that I would rather not use. ...
> ...
> > Any ideas?
>
> Yeah, dream on...
>
> How is the function supposed to know to do something based on an
> indication that isn't even made apparent to it???
>
> In short, pick one of the workarounds and run w/ it or make up another
> on your own (a global flag variable set/cleared in the calling examined
> in the function would be another kludge).
>
> --

Thanks for the global flag idea. It is more appealing of a work around than the others in my case.

But I'm surprised there isn't a way to know one of two things, either:
1) What the current command running on MATLAB is.
or
2) Whether the output will be suppressed or not.

For 1), MATLAB clearly knows the function handle (mfilename) and the arguments used to call it. Is it not able to reconstruct (or remember?) the function call that initiated these things?

For 2), I feel like there ought to be a issuppressed function/flag somewhere. Wouldn't the OnCleanup need to know that?

Subject: semi-colon suppress output of user defined function

From: dpb

Date: 12 May, 2011 21:47:43

Message: 4 of 16

On 5/12/2011 2:49 PM, Ben wrote:
...

> For 2), I feel like there ought to be a issuppressed function/flag
> somewhere. Wouldn't the OnCleanup need to know that?

"OnCleanup" of what, specifically, are you thinking?

You're asking for an output difference in two different scoping units;
the calling procedure knows whether it's to suppress it's output or not;
if it were the return value of the function you didn't want displayed
the desired syntax would (and, of course, does) work just fine--"ans"
wouldn't be shown.

OTOH, what you asked for was for an action inside the lower level
scoping unit; imo asking something outside to do that automagically
would be breaking every concept of modularity ever thought of regarding
data encapsulation and scope (other than Global which is apparent when
the solution/workaround using a global variable is thought about).

IOW, I couldn't disagree more strongly that it would be appropriate nor
feel more strongly it would be _a_bad_thing_ (tm) if there were such
connections.

Oh, one other idea pops up--I haven't tried this and don't feel
motivated enough given the aforementioned fact that I simply don't think
it's a good design for the calling routine to be telling the called
routine what to do (other than thru conventional means, anyway) but...

If the display is the result of a function or statement; what if the
function were written such that that were an optional output? I'm
thinking then the present semi-colon display handling might just give
you what you want and you could put the semi-colon on the code line in
the function.

Don't know, just a passing (not well-formed for lack of time spent)
thought...

--

Subject: semi-colon suppress output of user defined function

From: Rune Allnor

Date: 13 May, 2011 04:48:43

Message: 5 of 16

On May 12, 8:42 pm, "Ben " <ben-wal...@northwestern.edu> wrote:
> I have a function that I've written that prints some text to the command window.  I'd like to have that text not show up if the function is called with a semi-colon after it:
>
> >> MyFunc()
> Hello World!
>
> vs
>
> >> MyFunc();
>
> There are a few threads out there on this issue, but they all found work-arounds that I would rather not use.

No need to use work-arounds; simple program design will suffer.
Break the function in two parts. One part figures out what message
to print, the other actually prints the message:

message = MyFunc;
disp(message)

This way you can control whether or not to call the DISP function.

Rune

Subject: semi-colon suppress output of user defined function

From: Ben

Date: 13 May, 2011 14:28:04

Message: 6 of 16

My thanks for your posts, time, and thoughts.

@Rune:

> message = MyFunc;
> disp(message)
>

Ahh, Rune, thanks for this. Unfortunately, the message needs to be displayed while the function is running, not after. The function actually takes quite awhile to run (between a minute and a few hours, depending). The text printed to the screen lets the user know where in the process the function is. I was hoping to have a simple way for the user to suppress this output if they so desired. Displaying the message(s) after the function has completed wouldn't be helpful in my case. The solution I need is one that happens within the function, not afterwards.



@ dpb
> "OnCleanup" of what, specifically, are you thinking?
>
> You're asking for an output difference in two different scoping units;
> the calling procedure knows whether it's to suppress it's output or not;
> if it were the return value of the function you didn't want displayed
> the desired syntax would (and, of course, does) work just fine--"ans"
> wouldn't be shown.

I was hoping there would be a way for the called function to find out whether the calling procedure will be suppressing or not. Sure the calling procedure knows internally whether the return value will be suppressed, but is that information available anywhere else? I understand that I'm trying to push the boundaries and have MATLAB do something it wasn't precisely intended to do.

I thought that there was a slim chance this info might be in the function cleanup routines (http://www.mathworks.com/help/techdoc/ref/oncleanup.html)

>
> If the display is the result of a function or statement; what if the
> function were written such that that were an optional output? I'm
> thinking then the present semi-colon display handling might just give
> you what you want and you could put the semi-colon on the code line in
> the function.
>

As I just told Rune, the function prints status updates, so if the called function has to complete before it prints, it will be too late.


There are two very good solutions for me right now: both the global variable (i.e. SUPPRESS_MYFUNC = 1) that MyFunc accesses or checking whether nargout == 0 will work in my case. It's just less elegant than I was shooting for, but beggars can't be choosers, right?

Thanks again for the responses.

Subject: semi-colon suppress output of user defined function

From: Andy

Date: 13 May, 2011 14:44:05

Message: 7 of 16

The problem you're having is that the semicolon suppresses OUTPUT (that is, will not display the RETURNED values). 'Output' does not refer to all data printed to the command line during execution.

It sounds like you're implementing a 'verbose' option to your function, and this should be done via an optional argument, not the semicolon supression.

function MyFun(...,verbose)
  %...
  for ix = 1:1e5
    if verbose
      printf('Currently executing loop %d', ix);
    end
    % do whatever in the loop
  end
end

As a matter of good program design, your functions probably should never print directly to the screen. If you want them to, the caller should pass the 'verbose' option, and every print statement should be wrapped in:

if verbose
  print(...)
end

Subject: semi-colon suppress output of user defined function

From: Steven_Lord

Date: 13 May, 2011 15:48:08

Message: 8 of 16



"Ben " <ben-walker@northwestern.edu> wrote in message
news:iqjf5k$2ci$1@newscl01ah.mathworks.com...
> My thanks for your posts, time, and thoughts.
>
> @Rune:
>
>> message = MyFunc;
>> disp(message)
>>
>
> Ahh, Rune, thanks for this. Unfortunately, the message needs to be
> displayed while the function is running, not after. The function actually
> takes quite awhile to run (between a minute and a few hours, depending).
> The text printed to the screen lets the user know where in the process the
> function is. I was hoping to have a simple way for the user to suppress
> this output if they so desired. Displaying the message(s) after the
> function has completed wouldn't be helpful in my case. The solution I
> need is one that happens within the function, not afterwards.

Then the best approach in my opinion is to allow the user to pass an option
into your function to control how much information is displayed (similar to
the Display option accepted as part of the options structure by Optimization
Toolbox routines.)

http://www.mathworks.com/help/toolbox/optim/ug/f19175.html

> @ dpb
>> "OnCleanup" of what, specifically, are you thinking?
>>
>> You're asking for an output difference in two different scoping units;
>> the calling procedure knows whether it's to suppress it's output or not;
>> if it were the return value of the function you didn't want displayed the
>> desired syntax would (and, of course, does) work just fine--"ans"
>> wouldn't be shown.
>
> I was hoping there would be a way for the called function to find out
> whether the calling procedure will be suppressing or not. Sure the
> calling procedure knows internally whether the return value will be
> suppressed, but is that information available anywhere else? I understand
> that I'm trying to push the boundaries and have MATLAB do something it
> wasn't precisely intended to do.

I'm fairly certain there is no way to do exactly what you're looking to do;
see above for the solution I would recommend.

> I thought that there was a slim chance this info might be in the function
> cleanup routines
> (http://www.mathworks.com/help/techdoc/ref/oncleanup.html)
>
>>
>> If the display is the result of a function or statement; what if the
>> function were written such that that were an optional output? I'm
>> thinking then the present semi-colon display handling might just give you
>> what you want and you could put the semi-colon on the code line in the
>> function.
>>
>
> As I just told Rune, the function prints status updates, so if the called
> function has to complete before it prints, it will be too late.
> There are two very good solutions for me right now: both the global
> variable (i.e. SUPPRESS_MYFUNC = 1) that MyFunc accesses or checking
> whether nargout == 0 will work in my case. It's just less elegant than I
> was shooting for, but beggars can't be choosers, right?

I suggest NOT using a global variable for this for the usual reasons. The
big reason I don't like globals for this application is that any function
with access to the global workspace could "fiddle" with whether or not your
function displays information if it is called during execution of your
function, and unexpected behavior changes like this are often painful to try
to debug since it's caused by a variable value changing with no indication
in the code that it's changing.

--
Steve Lord
slord@mathworks.com
To contact Technical Support use the Contact Us link on
http://www.mathworks.com

Subject: semi-colon suppress output of user defined function

From: Steven_Lord

Date: 13 May, 2011 15:51:00

Message: 9 of 16



"Andy " <myfakeemailaddress@gmail.com> wrote in message
news:iqjg3l$570$1@newscl01ah.mathworks.com...
> The problem you're having is that the semicolon suppresses OUTPUT (that
> is, will not display the RETURNED values). 'Output' does not refer to all
> data printed to the command line during execution.
>
> It sounds like you're implementing a 'verbose' option to your function,
> and this should be done via an optional argument, not the semicolon
> supression.
>
> function MyFun(...,verbose)
> %...
> for ix = 1:1e5
> if verbose
> printf('Currently executing loop %d', ix);
> end
> % do whatever in the loop
> end
> end
>
> As a matter of good program design, your functions probably should never
> print directly to the screen. If you want them to, the caller should pass
> the 'verbose' option, and every print statement should be wrapped in:
>
> if verbose
> print(...)
> end

Or even better, you shouldn't just DISP/FPRINTF/etc. you should call a
logging function:

for ix = 1:1e5
    logDiagnostics(verbose, ...)
end

and let the logging function determine what information to write and to
where it should be written (screen if verbose is 'display', a log file if
verbose is 'logging', etc.) To add a new log destination or logging "level"
in the future all you need to do is modify the one logDiagnostics function
rather than dozens or hundreds of uses of "if verbose".

--
Steve Lord
slord@mathworks.com
To contact Technical Support use the Contact Us link on
http://www.mathworks.com

Subject: semi-colon suppress output of user defined function

From: Ben

Date: 13 May, 2011 16:15:05

Message: 10 of 16

"Andy" wrote in message <iqjg3l$570$1@newscl01ah.mathworks.com>...
> The problem you're having is that the semicolon suppresses OUTPUT (that is, will not display the RETURNED values). 'Output' does not refer to all data printed to the command line during execution.
>
> It sounds like you're implementing a 'verbose' option to your function, and this should be done via an optional argument, not the semicolon supression.
>
> function MyFun(...,verbose)
> %...
> for ix = 1:1e5
> if verbose
> printf('Currently executing loop %d', ix);
> end
> % do whatever in the loop
> end
> end
>
> As a matter of good program design, your functions probably should never print directly to the screen. If you want them to, the caller should pass the 'verbose' option, and every print statement should be wrapped in:
>
> if verbose
> print(...)
> end

Yes, you've got it! You've summed up my problem very well. I am indeed trying to add a 'verbose' option, but I was wondering if there was a way to "bend the rules" a little so that the verbose option could be gathered from how the command was typed in -- whether it had a semi-colon on the end or whether the calling procedure plans (future tense of the verb!) to suppress the output.

I don't want to add a 'verbose' argument to the function call, but I want to find another way of setting a flag that does the same thing. For instance, if this was done with the global variable approach:

function MyFun(...)
   global SUPPRESS_MYFUN;
   %...
   for ix = 1:1e5
     if SUPPRESS_MYFUN
       printf('Currently executing loop %d', ix);
     end
     % do whatever in the loop
   end
end

The principle is still exactly the same as you first outlined, but the flag is now set without adding additional arguments to MyFun. My approach on suppressing the printf's has always been along these lines, I was just curious what other ways there are of setting that flag.

Subject: semi-colon suppress output of user defined function

From: Ben

Date: 13 May, 2011 16:22:04

Message: 11 of 16

"Steven_Lord" <slord@mathworks.com> wrote in message <iqjk14$irg$1@newscl01ah.mathworks.com>...
>
>
> "Andy " <myfakeemailaddress@gmail.com> wrote in message
> news:iqjg3l$570$1@newscl01ah.mathworks.com...
> > The problem you're having is that the semicolon suppresses OUTPUT (that
> > is, will not display the RETURNED values). 'Output' does not refer to all
> > data printed to the command line during execution.
> >
> > It sounds like you're implementing a 'verbose' option to your function,
> > and this should be done via an optional argument, not the semicolon
> > supression.
> >
> > function MyFun(...,verbose)
> > %...
> > for ix = 1:1e5
> > if verbose
> > printf('Currently executing loop %d', ix);
> > end
> > % do whatever in the loop
> > end
> > end
> >
> > As a matter of good program design, your functions probably should never
> > print directly to the screen. If you want them to, the caller should pass
> > the 'verbose' option, and every print statement should be wrapped in:
> >
> > if verbose
> > print(...)
> > end
>
> Or even better, you shouldn't just DISP/FPRINTF/etc. you should call a
> logging function:
>
> for ix = 1:1e5
> logDiagnostics(verbose, ...)
> end
>
> and let the logging function determine what information to write and to
> where it should be written (screen if verbose is 'display', a log file if
> verbose is 'logging', etc.) To add a new log destination or logging "level"
> in the future all you need to do is modify the one logDiagnostics function
> rather than dozens or hundreds of uses of "if verbose".
>
> --
> Steve Lord
> slord@mathworks.com
> To contact Technical Support use the Contact Us link on
> http://www.mathworks.com

Steve,
I really like this logging idea -- thanks!

Subject: semi-colon suppress output of user defined function

From: Andy

Date: 13 May, 2011 16:24:05

Message: 12 of 16

"Ben" wrote in message <iqjle9$no8$1@newscl01ah.mathworks.com>...
> "Andy" wrote in message <iqjg3l$570$1@newscl01ah.mathworks.com>...
> > The problem you're having is that the semicolon suppresses OUTPUT (that is, will not display the RETURNED values). 'Output' does not refer to all data printed to the command line during execution.
> >
> > It sounds like you're implementing a 'verbose' option to your function, and this should be done via an optional argument, not the semicolon supression.
> >
> > function MyFun(...,verbose)
> > %...
> > for ix = 1:1e5
> > if verbose
> > printf('Currently executing loop %d', ix);
> > end
> > % do whatever in the loop
> > end
> > end
> >
> > As a matter of good program design, your functions probably should never print directly to the screen. If you want them to, the caller should pass the 'verbose' option, and every print statement should be wrapped in:
> >
> > if verbose
> > print(...)
> > end
>
> Yes, you've got it! You've summed up my problem very well. I am indeed trying to add a 'verbose' option, but I was wondering if there was a way to "bend the rules" a little so that the verbose option could be gathered from how the command was typed in -- whether it had a semi-colon on the end or whether the calling procedure plans (future tense of the verb!) to suppress the output.
>
> I don't want to add a 'verbose' argument to the function call, but I want to find another way of setting a flag that does the same thing. For instance, if this was done with the global variable approach:
>
> function MyFun(...)
> global SUPPRESS_MYFUN;
> %...
> for ix = 1:1e5
> if SUPPRESS_MYFUN
> printf('Currently executing loop %d', ix);
> end
> % do whatever in the loop
> end
> end
>
> The principle is still exactly the same as you first outlined, but the flag is now set without adding additional arguments to MyFun. My approach on suppressing the printf's has always been along these lines, I was just curious what other ways there are of setting that flag.

Why are you against adding a verbose argument (a very good solution) and in favor of using global variables (a very bad solution)?

Subject: semi-colon suppress output of user defined function

From: Ben

Date: 13 May, 2011 16:45:09

Message: 13 of 16

"Andy" wrote in message <iqjlv5$pg0$1@newscl01ah.mathworks.com>...
> Why are you against adding a verbose argument (a very good solution) and in favor of using global variables (a very bad solution)?


Well, the globals was just an example that there are other ways of setting a 'verbose' flag than passing it in as an argument. I originally wanted to set that flag by determining the presence of a semi-colon (or planned output suppressing) because that would be the easiest for the user. However, since that is seeming less and less likely, I'll have to find another way to set that flag.

A verbose argument is certainly the cleanest solution, I'll gladly concede that point. In fact, after thinking about it, I've started leaning that way. (Steve's logging function tipped the scales for me.) That said, globals do have an appeal that adding an argument does not. I actually have a set of functions (MyFun1, MyFun2, MyFun3...) and by adding a global SUPPRESS_MYFUNS flag, I could do that once then run any of them w/o having to add an additional argument each time I wanted to use one of these functions. It's a small thing, but I want these to be easy to use. (The counter argument that says "setting a global is inherently NOT user friendly" I have no answer to, other than to say, "yeah, you're right..." and then sit back sulkily).

Subject: semi-colon suppress output of user defined function

From: dpb

Date: 13 May, 2011 16:59:14

Message: 14 of 16

On 5/13/2011 10:48 AM, Steven_Lord wrote:
...

> I suggest NOT using a global variable for this for the usual reasons.
...

Indeed.

In fact I didn't suggest the GLOBAL as a recommendation but, I thought,
as an example of why the proposed idea of somehow a function modifying
its local behavior on the basis of information at the higher level of
scope was _a_bad_idea_ (tm).

Guess shows that one should never presume that intents will be
apparent... :(

--

Subject: semi-colon suppress output of user defined function

From: Scott

Date: 12 Jul, 2011 20:08:11

Message: 15 of 16

dpb <none@non.net> wrote in message <iqjo10$hj$1@speranza.aioe.org>...
> On 5/13/2011 10:48 AM, Steven_Lord wrote:
> ...
>
> > I suggest NOT using a global variable for this for the usual reasons.
> ...
>
> Indeed.
>
> In fact I didn't suggest the GLOBAL as a recommendation but, I thought,
> as an example of why the proposed idea of somehow a function modifying
> its local behavior on the basis of information at the higher level of
> scope was _a_bad_idea_ (tm).
>
> Guess shows that one should never presume that intents will be
> apparent... :(
>
> --

I was just looking for a similar solution. A user function that I don't "own" prints out a bunch of text to the screen that I don't want to see when calling it from my function. My colleague just informed me of "evalc". This stores the text that would be printed out to the screen as a variable.

Example:
storedtext = evalc('NotmyFun(input1, input2)');

Subject: semi-colon suppress output of user defined function

From: someone

Date: 12 Jul, 2011 21:00:47

Message: 16 of 16

"Ben" wrote in message <iqjn6l$e1$1@newscl01ah.mathworks.com>...
> "Andy" wrote in message <iqjlv5$pg0$1@newscl01ah.mathworks.com>...
> > Why are you against adding a verbose argument (a very good solution) and in favor of using global variables (a very bad solution)?
>
>
> Well, the globals was just an example that there are other ways of setting a 'verbose' flag than passing it in as an argument. I originally wanted to set that flag by determining the presence of a semi-colon (or planned output suppressing) because that would be the easiest for the user. However, since that is seeming less and less likely, I'll have to find another way to set that flag.
>
> A verbose argument is certainly the cleanest solution, I'll gladly concede that point. In fact, after thinking about it, I've started leaning that way. (Steve's logging function tipped the scales for me.) That said, globals do have an appeal that adding an argument does not. I actually have a set of functions (MyFun1, MyFun2, MyFun3...) and by adding a global SUPPRESS_MYFUNS flag, I could do that once then run any of them w/o having to add an additional argument each time I wanted to use one of these functions. It's a small thing, but I want these to be easy to use.

% As long as the verbose is the last agument of your functions
% you don't need to change the calls to your functions
% (if I understand your desire). For example, something like:

function output = MyFun1( arg1, arg2,arg3,verbose)
if nargin < 4
   verbose = 1; % or set the default as you like
end

*** insert rest of code here, including logging function ***


% Now you can cal MyFun1 with or without the verbose argument
% and it will either use verbose as is, or use the default condition.
% Also, take a look at the help for varargin

doc nargin
doc varargin

Tags for this Thread

Everyone's Tags:

Add a New Tag:

Separated by commas
Ex.: root locus, bode

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

Tag Activity for This Thread
Tag Applied By Date/Time
command history Ben 12 May, 2011 14:43:37
semicolon Ben 12 May, 2011 14:43:37
suppress output Ben 12 May, 2011 14:43:37
rssFeed for this Thread

Contact us