R: How to use list elements like arguments in ellipsis?

arguments, ellipsis, list, r, wrapper

Solution

This works, but I'm mystified by the design choices in that function:

lst <- list(
  a=structure(1:3, class="My_Class"), 
  b=structure(letters[1:3], class="My_Class")
)
env <- list2env(lst)
call <- as.call(append(list(fun), names(lst)))
eval(call, env)

To trick the function into working, you have to evaluate it in an environment where your list items are objects (this is what `list2env` does, creates that environment).

The terrible thing about that function is that it looks up objects in `parent.frame` based on their names, assuming that the `...` values are indeed names. I really don't understand why that function doesn't just do something like:

if(!all(vapply(list(...), class, "") == "My_Class")) stop(...)

Problem

I'm not sure if I labelled my question correct, but I give it a shot: I want to use a package with a function which uses an ellipsis, `func(...)`. All my arguments of class `My_Class` are in a list. As I have quite a lot of arguments, I'd like to avoid `func(arg1, arg2, arg3)`. So ideally I'd like to do `func( my_list )`. The problem is that the function looks like this ``` function(...) { cl <- match.call(expand.dots = FALSE) names <- lapply(cl[[2]],as.character) ev <- parent.frame() classes <- unlist(lapply(names,function(name){class(get(name,envir=ev))})) if( !all( classes == "My_Class" ) ) { stop("an argument to ... is not a My_Class") } } ``` So passing a list doesn't work. I also tried `func(my_list[[1]], my_list[[2]])` and `func(as.expression(my_list[[1]]))`, but even they do not work. As `func` treats the arguments as characters, `func(my_list[[1]])` becomes `chr [1:3] "[[" "my_list" "1"` inside, and `get(name,envir=ev)` crashes. I also tried `do.call(func, my_list)` but this again crashes as `my_list` is evaluated, therefore `name` inside the function is no longer a `character` but a `My_CLass` and again `get(name,envir=ev)` crashes. So my question: How can I accomplish to hand in a list without changing the package / underlying function? I thought about writing a wrapper, but I'm stuck as I do not even can `func(my_list[[1]])` make work. Maybe I'm just missing the correct term for my problem. Thanks in advance!

Original source