To debug a function foo in a file foo.R
foo <- function() {
a <- c(2, 3)
}
one can write a "driver" file
source("foo.R")
debug(f)
f()
This can trivially be extended for many such functions in the same scope.
Debugging a function bar() inside the body of foo is a bit tedious
foo <- function() {
bar <- function() {
a <- c(2, 3)
}
bar()
}
one can start from the same driver file (a test file, in practice), load bar() without actually running it, type debug(bar) at the debug prompt, and then run bar(). I'm wondering if there is a better way for multiple closures.
Is there a way to specify in the driver/test file that I want to debug the inner function bar, something along the lines of debug(foo::bar)?
Does R provide a standard syntax to refer to inner functions (aka nested functions, aka closures, etc.)?
Related questions:
Advanced debugging functionality in R?
You can just put a browser() at a point you want a debugger to be evoked:
foo <- function() {
print("In foo")
bar()
return(NULL)
}
bar <- function() {
print("In bar")
dash()
return(NULL)
}
dash <- function() {
print("In dash")
browser()
return(NULL)
}
foo()
Related
I'm frequently use Rstudio's "Go To Function Definition" (shortcut is F2) in order to navigate between many files and quickly access a function's definition / make changes (printing the function's definition is usually not enough).
In order to make my analysis quicker, many of my functions are memoised with the package 'memoise'. This is all and well, but when I use the "Go To Function Definition" button (or F2), it takes me to the memoise function. This is the result:
function (Date = Sys.Date(), Symbol)
{
hash <- `_digest`(c(list(Date, Symbol), lapply(`_additional`,
function(x) eval(x[[2L]], environment(x)))), algo = "sha512")
if (`_cache`$has_key(hash)) {
res <- `_cache`$get(hash)
}
else {
res <- withVisible(`_f`(Date = Date, Symbol = Symbol))
`_cache`$set(hash, res)
}
if (res$visible) {
res$value
}
else {
invisible(res$value)
}
}
One note - I tried defining the function and giving it its memoisation below it as follows:
foo <- function(x) { return(x) }
foo <- memoise::memoise(foo)
But when I run this on linux, any time I call foo I get an infinite loop. Oddly, it works well on Windows (and the F2 function works on windows with this method!). I need something that will work on a linux system as well as having F2 functionality work.
In R, is there a way to exit from the calling function and return a value? Something like return(), but from the parent function?
parent <- function(){
child()
# stuff afterward should not be executed
}
child <- function(){
returnFromParent("a message returned by parent()")
}
It seems stop() is doing something like that. What I want to do is to write a small replacement for stop() that returns the message that stop() writes to stderr.
Update after G5W's suggestion: I have a large number of checks, each resulting in a stop() if the test fails, but subsequent conditions cannot be evaluated if earlier checks fail, so the function must exit after a failing one. To do this 'properly', I would have to build up a huge if else construct, which I wanted to avoid.
Got it. I guess I was looking for something like this:
parent <- function(){
parent_killing_child()
print("do not run this")
}
parent_killing_child <- function(){
do.call(return, list("my message"), envir = sys.frame(-1))
}
parent()
Thanks for all the advices.
Disclaimer: This sounds a XY problem, printing the stop message to stdout has few to no value, if interactive it should not be a problem, if in a script just use the usual redirection 2 > &1 to write stderr messages to stdout, or maybe use sink as in answer in this question.
Now, if I understood properly what you're after I'll do something like the following to avoid too much code refactoring.
First define a function to handle errors:
my_stop <- function() {
e <- geterrmessage()
print(e)
}
Now configure the system to send errors to your function (error handler) and suppress error messages:
options(error = my_stop)
options(show.error.messages=FALSE)
Now let's test it:
f1 <- function() {
f2()
print("This should not be seen")
}
f2 <- function() {
stop("This is a child error message")
}
Output:
> f1()
[1] "Error in f2() : This is a child error message\n"
For the parent function, make a list of tests. Then loop over the tests, and return your message at the first failed test. Subsequent tests will not be executed after the first failure.
Sample code:
test1 <- function(){criteria <- T; return(ifelse(criteria,T,F))}
test2 <- function(){criteria <- F; return(ifelse(criteria,T,F))}
test3 <- function(){criteria <- T; return(ifelse(criteria,T,F))}
parent <- function() {
tests <- c('test1', 'test2', 'test3')
for (i in 1:length(tests)) {
passed <- do.call(tests[i],args = list())
#print(passed)
if (!passed){
return(paste("Testing failed on test ", i, ".", sep=''))
}
}
return('Congrats! All tests passed!')
}
parent()
Update
Kudos to #chris for their clever application of do.call() in their successful solution.
In five years since then, the R team has released the rlang package within the tidyverse, which provides the apt function rlang::return_from() in tandem with rlang::return_to().
While base::return() can only return from the current local frame,
these two functions will return from any frame on the current
evaluation stack, between the global and the currently active context.
They provide a way of performing arbitrary non-local jumps out of the
function currently under evaluation.
Solution
Thus, you can simply do
child <- function() {
rlang::return_from(
# Return from the parent context (1 frame back).
frame = rlang::caller_env(n = 1),
# Return the message text.
value = "some text returned by parent()"
)
}
where the parent is identified via rlang::caller_env().
Results
When called from a parent() function
parent <- function() {
child()
# stuff afterward should not be executed
return("text that should NOT be returned by parent()")
}
the child() function will force parental behavior like this:
parent()
#> [1] "some text returned by parent()"
Bonus
See my solution here for throwing an error from a parent (or from any arbitrary "ancestor").
Python has a pass statement, a null operation, which can be a useful placeholder before code is complete, for example in Python:
def example_function():
pass
# stuff to do here
Is there an equivalent in R? Thank you.
Just have an empty function body:
foo = function(){
}
You should probably also add a comment, and a warning maybe?
foo = function(){
# write this tomorrow
warning("You ran foo and I havent written it yet")
}
Same thing with an if expression:
if(x==1){
# do this bit later
}else{
message("x isnt 1")
}
If you don't want NULL returned,and you don't want to wrap your function call with invisible(), you can include invisible() inside of the function body. This returns nothing:
my_func <- function(x){
invisible()
}
my_func(100)
I am trying to figure out how to return an object if an if statement is TRUE from a function foo within a parent function bar, and not execute following code in bar; or if FALSE, execute the following code in bar. In the function bar2 below I can test the output of foo and then execute more code in bar2 if the output of foo is NULL. However, in trying to reduce lines of code used, I want to know if I can somehow prevent "howdy" from printing in the bar function if the if statement in the function foo is TRUE. stop would do it but is signals an error, which is not what is happening here. Basically I'm looking for an equivalent of stop but returning an object w/o error.
foo <- function(x){
if(x < 10){
"hello world"
} else
{ NULL }
}
bar <- function(y){
foo(y)
"howdy"
}
bar2 <- function(y){
out <- foo(y)
if(!is.null(out)){
out
} else
{
"howdy"
}
}
bar(5)
[1] "howdy"
bar2(5)
[1] "hello world"
So the reason bar is not working, is because of scope. You have to perform some form of check in bar; this is unavoidable.
What you might be looking for is return instead of stop:
bar <- function(y){
if (!is.null(foo(y))) {
return("hello world") # breaks out of the function
}
print("this will never print when foo doesn't return NULL")
"howdy" # ending part, so it would be returned only if foo(y) != "h..."
}
Extra:
I am not sure if you got this part, but the reason your functions work is because you implicitly return something when something is called, while it is the ending part of a function.
E.g.:
test <- function() {
"hello world"
a <- "hello world"
}
Running test() won't return the "hello world" it would otherwise, because the last thing ran is not a call.
The language is R.
I have a couple of files:
utilities.non.foo.R
utilities.foo.R
utilities.R
foo is an in-house package that has been cobbled together (for image processing, although this is irrelevant). It works great, but only on Linux machines, and it is a huge pain to try and compile it even on those.
Basically, utilities.foo.R contains a whole lot of functions that require package foo.
The functions in here are called functionname.foo.
I'm about to start sharing this code with external collaborators who don't have this package or Linux, so I've written a file utilities.non.foo.R, which contains all the functions in utilities.foo.R, except the dependency on package foo has been removed.
These functions are all called functionname.non.foo.
The file utilities.R has a whole heap of this, for each function:
functionname <- function(...) {
if ( fooIsLoaded() ) {
functionname.foo(...)
} else {
functionname.non.foo(...)
}
}
The idea is that one only needs to load utilities.R and if you happen to have package foo (e.g. my internal collaborators), you will use that backend. If you don't have foo (external collaborators), you'll use the non-foo backend.
My question is: is there some way to do the redirection for each function name without explicitly writing the above bit of code for every single function name?
This reminds me of how (e.g.) there is a print method, a print.table, print.data.frame, etc, but the user only needs to use print and which method is used is chosen automatically.
I'd like to have that, except the method.class would be more like method.depends_on_which_package_is_loaded.
Is there any way to avoid writing a redirection function per function in my utilities.R file?
As Dirk says, just use a package. In this case, put all your new *.non.foo functions in a new package, which is also called foo. Distribute this foo to your collaborators, instead of your in-house version. That way your utilities code can just be
functionname <- function(...) functionname.foo(...)
without having to make any checks at all.
Here is an idea: write a function that sets f to either f.foo or f.non.foo. It could be called in a loop, over all functions in a given namespace (or all functions whose name ends in .foo).
dispatch <- function(s) {
if ( fooIsLoaded() ) {
f <- get( paste(s, "foo", sep=".") )
} else {
f <- get( paste(s, "non.foo", sep=".") )
}
assign( s, f, envir=.GlobalEnv ) # You may want to use a namespace
}
f.foo <- function() cat("foo\n")
f.non.foo <- function() cat("non-foo\n")
fooIsLoaded <- function() TRUE
dispatch("f")
f()
fooIsLoaded <- function() FALSE
dispatch("f")
f()
A simpler solution would be to give the same name
to both functions, but put them in different namespaces/packages.
This sounds quite inefficient and inelegant, but how about
funify = function(f, g, package="ggplot2") {
if(paste("package:", package, sep="") %in% search()) f else
{ message("how do you intend to work without ", package) ; g}
}
detach(package:ggplot2)
foo = funify(paste, function(x) letters[x])
foo(1:10)
library(ggplot2)
foo = funify(paste, function(x) letters[x])
foo(1:10)