1

I am trying to be clever and write a "stopcat" function that is in essence shorthand for stop( sprintf( "a string thing %d", val ) )

Here is a small snippet that doesn't work

library( tidyverse ) # For !!
stopcat = function( str, ... ) {
  msg = sprintf( str, ... )
  eval( expr( stop( !!msg ) ), parent.frame(1) )
}

pig = function() {
  cat( "piggy\n" )
  stopcat( "no way! %d", 6 )
  24 * 44
}
pig()

It prints out

 Error in eval(expr(stop(!!msg)), parent.frame(1)) : no way! 6 

but I want

 Error in pig : no way! 6 

Any thoughts?

I found related post How to get the name of the calling function inside the called routine? but the details there do not seem to apply to stop (or I can't understand what was said, perhaps)

miratrix
  • 191
  • 2
  • 12

1 Answers1

1

I don't think you can fool stop by manipulating the evaluation context like that. If you really need to identify that function, you might try grabbing the function name and adding that to the error message and turning off the default expression label. For example

stopcat <- function( str, ... ) {
  msg <- sprintf( str, ... )
  fun <- deparse(sys.call(1)[[1]])
  msg <- paste0("(in ", fun, "): ", msg)
  stop( msg, call.=FALSE)
}

pig <- function() {
  cat( "piggy\n" )
  stopcat( "no way! %d", 6 )
  24 * 44
}
pig()
# piggy
#  Error: (in pig): no way! 6 
MrFlick
  • 195,160
  • 17
  • 277
  • 295