Dear list, I wonder if there's a clever way to fine control the exact way arguments are dispatched via R's "three dots" argument ....
Consider the following use case: - you have a function foobar() that calls foo() which in turn calls bar() - *both* foo() and bar() have an argument that's called y, but they each have a *different meaning* - in the call to foobar(), you would like to say "here's the y for foo() and here's the y for bar()". *That's what I would like to accomplish*. If you simply call foobar(x = "John Doe", y = "hello world"), y only get's dispatched to foo() as in the call to bar() things would have to be explicit in order to be dispatched (i.e. the call would have to be bar(x = x, y = y) instead of bar(x = x, ...): foo <- function(x, y = "some character", ...) { message("foo ----------") message("foo/threedots") try(print(list(...))) message("foo/y") try(print(y)) bar(x = x, ...)} bar <- function(x, y = TRUE, ...) { message("bar ----------") message("bar/threedots") try(print(list(...))) message("bar/y") try(print(y)) return(paste0("hello: ", x))} foobar <- function(x, ...) { message("foobar ----------") message("foobar/threedots") try(print(list(...))) foo(x = x, ...)} foobar(x = "John Doe", y = "hi there")# foobar ----------# foobar/threedots# $y# [1] "hi there"# # foo ----------# foo/threedots# list()# foo/y# [1] "hi there"# bar ----------# bar/threedots# list()# bar/y# [1] TRUE# [1] "hello: John Doe" What I conceptionally would like to be able to do is something like this: foobar(x = "John Doe", y_foo = "hello world!", y_bar = FALSE) Here's an approach that works but that also feels very odd: foo <- function(x, y = "some character", ...) { message("foo ----------") message("foo/threedots") try(print(list(...))) message("foo/y") arg <- paste0("y_", sys.call()[[1]]) if (arg %in% names(list(...))) { y <- list(...)[[arg]] } try(print(y)) bar(x = x, ...)} bar <- function(x, y = TRUE, ...) { message("bar ----------") message("bar/threedots") try(print(list(...))) message("bar/y") arg <- paste0("y_", sys.call()[[1]]) if (arg %in% names(list(...))) { y <- list(...)[[arg]] } try(print(y)) return(paste0("hello: ", x))} foobar(x = "John Doe", y_foo = "hello world!", y_bar = FALSE)# foobar ----------# foobar/threedots# $y_foo# [1] "hello world!"# # $y_bar# [1] FALSE# # foo ----------# foo/threedots# $y_foo# [1] "hello world!"# # $y_bar# [1] FALSE# # foo/y# [1] "hello world!"# bar ----------# bar/threedots# $y_foo# [1] "hello world!"# # $y_bar# [1] FALSE# # bar/y# [1] FALSE# [1] "hello: John Doe" How would you go about implementing something like this? I also played around with S4 method dispatch to see if I could define methods for a signature argument ..., but that didn't go too well (and it's probably a very bad idea anyway): setGeneric( name = "foo", signature = c("x", "..."), def = function(x, ...) standardGeneric("foo") ) setMethod( f = "foo", signature = signature(x = "character", "..." = "MyThreeDotsForBar"), definition = function(x, ...) bar(x = x))## --> does not work [[alternative HTML version deleted]] ______________________________________________ R-help@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.