Open martinju opened 1 year ago
Hello.
Is there a simple way to detect whether either a global handler is registered in the current session,
handlers(global = NA)
will return TRUE if there's one registered, otherwise FALSE.
or whether foo() is wrapped within with_progress
No, I don't think that's possible. To generalize your question, what you're after is a way to see if it's possible to detect, from foo()
, that there is a handler for conditions of class some_handler
the following call:
withCallingHandlers({
foo()
}, some_handler = function(cond) {
...
})
I don't think that's possible in R, but I'm not 100% sure. If you could, please reach out on R-devel and ask about this - it could be an interesting feature to have in R.
In progressr, I could of course have with_progress()
to temporarily set an internal flag, or an R option, that can be queried, e.g. has_progressr_handlers()
. But, before thinking about that ...
such that foo() will display a progress bar in my console?
What are you really trying to achieve here? Note, even if you could know that there are progression handlers actively "listening", you would not know how they report on the progress. For example, handlers("beep")
would not "display a progress bar in my console". There are several other handlers that render progress elsewhere (and more to come).
handlers(global = NA)
will return TRUE if there's one registered, otherwise FALSE.
Thanks, that solves my problem assuming everyone uses the global option (which may not be a reasonable assumption).
If you could, please reach out on R-devel and ask about this - it could be an interesting feature to have in R.
I'll try to see if I can make that happen.
In progressr, I could of course have
with_progress()
to temporarily set an internal flag, or an R option, that can be queried, e.g.has_progressr_handlers()
. But, before thinking about that ...
I think that would be very useful for my use case, see below.
What are you really trying to achieve here?
Short story: I want to set different default behavior in a function depending on whether progress handler is enabled or not.
Long story: My use case is a function that splits a potentially memory hungry task into smaller subtasks which are handled separately, and progress is reported for every completed subtask via progressr
.
The task splitting reduces the memory consumption significantly, at the cost of an increase in the computation time.
With smaller dimensional data input to the function, memory consumption is not an issue, but the computation time still increases. These cases can be identified based on the input. In these cases, the only reason for doing the splitting is if the user wants to display the computation progress. If the user has not registered a progress handler, it would be preferable to not split the tasks to save some computation time.
So, if I could detect whether the user has enabled progress reporting (of any kind), I can set the default behavior to do task splitting when it is enabled, and disable the task splitting if progress reporting is not enabled by the user.
So, if I could detect whether the user has enabled progress reporting (of any kind), I can set the default behavior to do task splitting when it is enabled, and disable the task splitting if progress reporting is not enabled by the user.
I strongly recommend against this. The user might have enabled the global progress handler for other reasons that are unrelated to your package and your function. It's important to always remember that our packages and functions can be used in contexts that we as developers cannot predict or know why and when. Some developers use similar things like if (requireNamespace("foo")) { do this } else { otherwise that }
. That introduces a non-deterministic behavior and a major surprise for the end-user; that foo package might have been installed for other reasons.
I highly value your recommendations on this.
However, I don't quite understand the big issue with my suggested approach.
Based on the input arguments to foo()
, I am already setting default values for internal parameters related to computation speed/memory usage (within the function call to foo() only).
The output of the function foo()
is exactly the same regardless of how I set these internal parameters.
If a progress handler is enabled, the 'visual behavior' of the call to foo()
changes since a progress bar is displayed (or rendered elsewhere).
Now, I also want the computation speed/memory usage (of the call to foo()
only) to depend on whether the progress handler is enabled.
The behavior of other functions, packages and global parameters are not changed depending on whether the package with the function foo()
is installed/loaded or not.
It would be very helpful if you could elaborate on your view related to this.
Hi
Say I have a function
foo()
which contains code displaying a progress bar withprogressr
. Is there a simple way to detect whether either a global handler is registered in the current session, or whetherfoo()
is wrapped withinwith_progress
such that foo() will display a progress bar in my console?Thanks!