Just following up to check if anyone has had time to look over these patches.

Frederick

On Wed, Dec 08, 2021 at 12:24:47AM -0800, Frederick Eaton wrote:
Dear R Core Team,

I'm attaching a proposed patch to hopefully address my confusions regarding the 
documentation of browser(). I'm not sure if all the material I added is 
correct, but I made experiments to confirm that the behavior is at least 
roughly as described.

   patch ./src/library/base/man/browser.Rd < browser.patch

Also, here is a patch to support multiple mouse buttons in getGraphicsEvent(). 
This must be edited before it can be applied, I decided to keep the old code in 
an 'if(0)' to help make it clearer that my code is essentially doing the same 
thing.

   
https://github.com/navarum/tweaks/blob/master/r/patches/0001-Add-support-for-multiple-mouse-buttons.patch
   wget -O - 
https://raw.githubusercontent.com/navarum/tweaks/master/r/patches/0001-Add-support-for-multiple-mouse-buttons.patch
 | patch -p1

It would be useful to have support in R for more than three mouse buttons 
because this enables the use of the mouse wheel (buttons 4 and 5), which can 
provide a more convenient interface when adjusting numbers and graphics and so 
on. I also have shift+wheel bound to buttons 6 and 7 via xbindkeys and xte, 
which I use for horizontal scrolling, via a trick from the web somewhere:

   $ cat .xbindkeysrc.scm | grep xte
   (xbindkey '(shift "b:4") "xte 'mouseclick 6'")
   (xbindkey '(shift "b:5") "xte 'mouseclick 7'")

I hope that these contributions can be found acceptable.

Thank you in advance,

Frederick



On Mon, Nov 22, 2021 at 09:13:58AM -0800, Frederick Eaton wrote:
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


--- browser-orig.Rd     2021-12-07 22:35:51.991222137 -0800
+++ browser-new.Rd      2021-12-07 23:53:36.414106296 -0800
@@ -45,8 +45,16 @@
  will be simpler.

  The \code{skipCalls} argument should be used when the \code{browser()}
-  call is nested within another debugging function:  it will look further
-  up the call stack to report its location.
+  call is nested within another debugging function: it will look further
+  up the call stack to report its location. However, currently this
+  argument only affects the \code{Called from:} message printed before
+  the first \code{Browse>} prompt, and does not change the evaluation
+  environment of the expressions entered there, nor the output of the
+  \code{where} command. It is not clear when this argument would be
+  useful. It is for example currently impossible to change occurrences
+  of \code{stopifnot(x)} to act like \code{browser(expr=!x)} by
+  redefining \code{stopifnot()}; this must instead be done through a
+  textual search-and-replace or \code{options(error=recover)}.

  At the browser prompt the user can enter commands or \R expressions,
  followed by a newline.  The commands are
@@ -58,11 +66,9 @@
    \item{\code{f}}{finish execution of the current loop or function}
    \item{\code{help}}{print this list of commands}
    \item{\code{n}}{evaluate the next statement, stepping over
-      function calls.  For byte compiled functions interrupted by
-      \code{browser} calls, \code{n} is equivalent to \code{c}.}
+      function calls.}
    \item{\code{s}}{evaluate the next statement, stepping into
-      function calls.  Again, byte compiled functions make
-      \code{s} equivalent to \code{c}.}
+      function calls.}
    \item{\code{where}}{print a stack trace of all active function calls.}
    \item{\code{r}}{invoke a \code{"resume"} restart if one is
      available; interpreted as an \R expression otherwise. Typically
@@ -71,6 +77,15 @@
    \item{\code{Q}}{exit the browser and the current evaluation and
      return to the top-level prompt.}
  }
+
+  Both \code{n} and \code{s} also step out of function calls. However,
+  it is currently not possible with these commands to step out of the
+  function which called \code{browser()}. At the end of the function
+  which called \code{browser}, \code{n} and \code{s} are both equivalent
+  to \code{c}. These commands (\code{n} and \code{s}) are also
+  equivalent to \code{c} when trying to use them inside byte compiled
+  functions interrupted by \code{browser} calls.
+
  Leading and trailing whitespace is ignored, except for an empty line.
  Handling of empty lines depends on the \code{"browserNLdisabled"}
  \link[=options]{option}; if it is \code{TRUE}, empty lines are ignored.

______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel

Reply via email to