[Rd] meaning of browser(skipCalls=)

Frederick Eaton |reder|k @end|ng |rom o|b@net
Mon Nov 22 18:13:58 CET 2021


Dear R Devel,

I have been advised to use "options(error=recover)" to enable
debugging on errors. But sometimes it would seem more convenient to
override "stopifnot", for example:

     stopifnot = function(b) { if(!b) { browser(skipCalls=1); } }

However, this doesn't do what I expected. On looking closer I find
that the "skipCalls" argument seems to be ignored except when printing
the "Called from: " message; it does not affect the evaluation context
or the output of 'where':

     > var=2; f=function(){var=1; browser(skipCalls=0)}; f()
     Called from: f()
     Browse[1]> var
     [1] 1
     Browse[1]> where
     where 1: f()

     Browse[1]> Q
     > var=2; f=function(){var=1; browser(skipCalls=1)}; f()
     Called from: top level 
     Browse[1]> var
     [1] 1
     Browse[1]> where
     where 1: f()

     Browse[1]> Q
     > var=2; f=function(){var=1; browser(skipCalls=2)}; f()
     Called from: top level 
     Browse[1]> var
     [1] 1
     Browse[1]> where
     where 1: f()

     Browse[1]> Q

So it appears that the "browser()" API does not actually make it
possible to call this built-in function from within another R function
and thereby emulate the same behavior as calling browser() directly.

If this is the case, it might be good to have it fixed or documented.
I am aware of "browser(expr=)", but this requires editing the
particular call that failed. The documentation for "browser()" led me
to hope that my use case would be supported, if only because it admits
that users might want to build other debugging functions with
browser(): "The 'skipCalls' argument should be used when the
'browser()' call is nested within another debugging function". An
example where this 'skipCalls' parameter is used to build a useful
debugging function would help to clarify its English description in
the manual.

Also, from the browser() command line I could not find a way to step
*out* of the current function. This would have been a way to recover
from skipCalls not working as expected. Am I missing something? For
example is there some command other than "n", where the below
interaction could pause before "hi" and "bye"?

     > f=function(){browser(); message("in f"); message("out f")}; f(); message("hi"); message("bye")
     Called from: f()
     Browse[1]> n
     debug at #1: message("in f")
     Browse[2]> n
     in f
     debug at #1: message("out f")
     Browse[2]> n
     out f
     hi
     bye

If it is not possible for the R debugger to step out of a function, it
would be good to document that too, maybe after the list of browser
prompt commands in "?browser". Being confined within a single function
is not an obvious disability for a debugger to have.

I feel that R is an excellent tool, but sometimes I think that if the
shortcomings of the system were better documented, then this would
save users a lot of time in certain cases.

Thank you,

Frederick



More information about the R-devel mailing list