R pattern to modify arguments passed to generic function

前端 未结 1 867
你的背包
你的背包 2021-02-14 14:05

I have a generic function called foo. It operates differently on the classes bar and baz but there is some shared pre-processing that need

1条回答
  •  失恋的感觉
    2021-02-14 14:34

    1) Layer foo on top of actual generic Change foo to perform the preliminary code and invoke foo_ a new generic as shown. Rename foo.bar and foo.baz to foo_.bar and foo_.baz respectively so that we are left with (have also added newlines to the example):

    foo <- function(x) {
        x <- x * 10
        foo_(x)
    }
    
    foo_ <- function(x) UseMethod("foo_")
    
    foo_.bar <- function(x) cat("Foo!", x, "\n")
    foo_.baz <- function(x) cat("Baz!", x, "\n")
    

    Now test it out:

    a <- structure(1:5, class="bar")
    b <- structure(6:10, class="baz")
    
    foo(a)
    ## Foo! 10 20 30 40 50
    foo(b)
    ## Baz! 60 70 80 90 100
    

    For an example of this in a widely used package see the source of dplyr::mutate

    2) NextMethod Another way would be to give every object a class vector of two classes with "foo" made a subclass of "bar" in the case of a and of "baz" in the case of b. Then use NextMethod. Solution (1) seems simpler and it may seem weird that "foo" is a subclass of both "bar" and "baz" but here is an example of this one just in case:

    foo <- function(x) UseMethod("foo")
    
    foo.foo <- function(x) {
        x <- x * 10
        NextMethod()
    }
    foo.bar <- function(x) cat("Foo!", x, "\n")
    foo.baz <- function(x) cat("Baz!", x, "\n")
    

    Test it noting that we have changed the definitions of a and b so that they work with this approach:

    a <- structure(1:5, class= c("foo", "bar"))
    b <- structure(6:10, class = c("foo", "baz"))
    
    foo(a)
    ## Foo! 10 20 30 40 50
    foo(b)
    ## Baz! 60 70 80 90 100
    

    0 讨论(0)
提交回复
热议问题