Home > Enterprise >  Why are my ... argmuments still evaluated despite me trying to defuse them?
Why are my ... argmuments still evaluated despite me trying to defuse them?

Time:11-24

I am struggling to defuse my ... arguments in one context in particular and I cannot understand why.

I can make a function like this and defuse ... appropriately:

library(dplyr)
library(tidyr)

fill_na <- function(.x,...){

  dotArgs <- rlang::dots_list(...,.named=TRUE,.homonyms="last")
  tidyr::replace_na(.x,dotArgs)  

}

df <- tibble::tribble(
  ~colA, ~colB,
  "a",   1,
  "b",   2,
  "c",   NA,
  NA,    4
)

> fill_na(df,colA="c",colB=2)
# A tibble: 4 × 2
  colA   colB
  <chr> <dbl>
1 a         1
2 b         2
3 c         2
4 c         4

Great, but if I make this function

myFun <- function(inside_of,from_what, ... ,.metadata_defaults=list("Gender"="Undefined","Age"=35),.by_maxFormantHz=TRUE,.recompute=FALSE,.package="superassp"){

    dotArgs <- rlang::dots_list(...,.named=TRUE,.homonyms="last")
    return(1)

}

I get this result:

> myFun(inside_of=ae,from_what=forest,fs=fm, fbw=bw)
Error in rlang::dots_list(..., .named = TRUE, .homonyms = "last") : 
  object 'fm' not found

How come the arguments are not defused here, but were in the first example?

CodePudding user response:

The dots aren’t defused in either of your functions. Per the docs, dots_list()evaluate[s] all arguments contained in ... and return[s] them as a list” (emphasis added). You just don’t notice it in your fill_na() function because you’re not passing it an undefined variable, so the lack of defusing doesn’t cause any problems.

If you want to defuse the dots, use enquos().

myFun <- function(inside_of,
                  from_what,
                  ...,
                  .metadata_defaults = list("Gender" = "Undefined", "Age" = 35),
                  .by_maxFormantHz = TRUE,
                  .recompute = FALSE,
                  .package = "superassp") {
    dotArgs <- rlang::enquos(...)
    return(1)
}

myFun(inside_of = ae, from_what = forest, fs = fm, fbw = bw)
# 1

You can then use !!!dotArgs inside dots_list() when you’re ready to evaluate.

  • Related