[R-pkg-devel] NOTE about use of `:::`

Duncan Murdoch murdoch@dunc@n @end|ng |rom gm@||@com
Thu Dec 15 10:39:22 CET 2022


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.urbanek using 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.kepplinger using 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 using r-project.org mailing list
>>> https://stat.ethz.ch/mailman/listinfo/r-package-devel
>>>
>>
>>
> 
> 	[[alternative HTML version deleted]]
> 
> ______________________________________________
> R-package-devel using r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-package-devel



More information about the R-package-devel mailing list