I think I will go with the suggestion of creating a new empty environment, adding only the argument parsing function. Moreover I will use the same name as the user-facing function that's being invoked, i.e.,
foo <- function(...) { call <- match.call(expand.dots = TRUE) call[[1]] <- quote(parse_args) envir <- new.env(parent = parent.frame()) envir$foo <- parse_args eval(call, envir) } This way a trace-back shows the function the user expects, without having to export the parsing function or duplicate the code in the user-facing functions. Thanks again everyone for the suggestions. All the best, David On Thu, Dec 15, 2022 at 4:39 AM Duncan Murdoch <murdoch.dun...@gmail.com> wrote: > If you want the name of the function to appear, then you can put the > function in an environment whose parent is where most of the evaluation > should take place. For example, > > f <- function(...) { > call <- match.call(expand.dots = TRUE) > call[[1]] <- quote(parse_args) > envir <- new.env(parent = parent.frame()) > envir$parse_args <- parse_args > > eval(call, envir) > } > > parse_args <- function(...) { > cat("args were ", names(list(...)), "\n") > stop("Error in parse_args") > } > > f(a = 1, b = 2) > #> args were a b > #> Error in parse_args(a = 1, b = 2): Error in parse_args > > Duncan Murdoch > > > On 14/12/2022 8:35 p.m., David Kepplinger wrote: > > Thank you both for the suggestions. I would prefer a clean stack trace in > > case of errors as input errors are caught by this function and hence > users > > might very well see errors emitted from it. It seems more informative to > me > > if the error message would say "Error in .parse_args…" than "Error in > > new.env(…". But since this solution was suggested by both of you it is > > likely that CRAN too would demand this or a similar approach instead of > > using `:::`. I know `:::` is expansive, but the computations that follow > > are typically at least a few minutes so anything that takes less than a > few > > seconds won't be noticeable. > > > > I also thought about using `...` before, but then the signature of the > > user-facing functions would be incomplete and IDEs won't be able to > provide > > suggestions. > > > > Thanks for the help! > > > > -- David > > > > On Wed, Dec 14, 2022 at 7:11 PM Simon Urbanek < > simon.urba...@r-project.org> > > wrote: > > > >> David, > >> > >> why not > >> > >> call[[1]] <- parse_args > >> > >> The assignment is evaluated in your namespace so that makes sure the > call > >> is that of your function. The only downside I see is that in a stack > trace > >> you'll see the definition instead of the name. > >> Or possibly > >> > >> do.call(parse_args, as.list(call[-1])) > >> > >> Cheers, > >> Simon > >> > >> PS: Note that ::: is expensive - it probably doesn't matter here, but > >> would in repeatedly called functions. > >> > >> > >>> On 15/12/2022, at 12:19 PM, David Kepplinger < > david.kepplin...@gmail.com> > >> wrote: > >>> > >>> Dear List, > >>> > >>> I am working on updating the pense package and refactored some of the > >>> methods. I have several functions which take the same arguments, hence > >> I'm > >>> sending all these arguments to an internal function, called > >> `parse_args()`. > >>> Since I want to evaluate the arguments in the caller's environment, I'm > >>> using the following code > >>> > >>> call <- match.call(expand.dots = TRUE) > >>> call[[1]] <- quote(pense:::parse_args) > >>> args <- eval.parent(call) > >>> > >>> Of course, R CMD CHECK complains about the use of `:::`, as it's almost > >>> never needed. I think the above usage would fall into that area of > >>> "almost", but I'm not sure if (a) there's a better approach and (b) the > >>> CRAN team would agree with me. I would have to test (b) by submitting > and > >>> working with the CRAN team, but I wanted to ask the list first to see > if > >>> I'm missing something obvious. I don't want to export the function > >>> parse_args() as it's not useful for a user, and the use is truly > >> internal. > >>> > >>> Thanks and all the best, > >>> David > >>> > >>> [[alternative HTML version deleted]] > >>> > >>> ______________________________________________ > >>> R-package-devel@r-project.org mailing list > >>> https://stat.ethz.ch/mailman/listinfo/r-package-devel > >>> > >> > >> > > > > [[alternative HTML version deleted]] > > > > ______________________________________________ > > R-package-devel@r-project.org mailing list > > https://stat.ethz.ch/mailman/listinfo/r-package-devel > > [[alternative HTML version deleted]] ______________________________________________ R-package-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-package-devel