2016-01-30 36 views
3

使用R6類時,在調用其他方法的類之外定義方法的正確方法是什麼?定義在R6對象外部調用其他方法的方法

請考慮以下示例,其中函數func可能調度到另一個函數,如果它正在交互使用。但是,如果這樣做,另一個功能就無法訪問私有環境。如果我以這種方式定義類,我應該傳遞一個環境嗎?

## General function defined outside R6 class 
func <- function(x) { 
    if (missing(x) && interactive()) { 
    ifunc() 
    } else { 
    private$a <- x * x 
    } 
} 

## If interactive, redirect to this function 
ifunc <- function() { 
    f <- switch(menu(c('*', '+')), '1'=`*`, '2'=`+`) 
    private$a <- f(private$a, private$a) 
} 

## R6 test object 
Obj <- R6::R6Class("Obj", 
    public=list(
    initialize=function(a) private$a <- a, 
    geta=function() private$a, 
    func=func # defined in another file 
), 
    private=list(
    a=NA 
) 
) 

## Testing 
tst <- Obj$new(5) 
tst$func(3) 
tst$geta() # so func sees 'private' 
# [1] 9 

tst$func() # doesn't see 'private' 

錯誤ifunc()(從#3):對象 '私人' 未找到

回答

2

你所面對的問題是,你以這樣的方式,該定義funcifunc實現只在類定義內部有意義 - 但不完全。你得到一個錯誤,因爲ifunc被實現,就好像它知道你的類的內部(它指的是私有的),但它不知道。你從來沒有真正把它包含到你的類定義中。所以,你必須在func指私有成員函數ifunc,包括ifunc到類:

func <- function(x) { 
    if (missing(x) && interactive()) { 
     private$ifunc() 
    } else { 
     private$a <- x * x 
    } 
} 


ifunc <- function() { 
    f <- switch(menu(c('*', '+')), '1'=`*`, '2'=`+`) 
    private$a <- f(private$a, private$a) 
} 


Obj <- R6::R6Class(
    "Obj", 
    public=list(
     initialize=function(a) private$a <- a, 
     geta=function() private$a, 
     func=func # defined in another file 
    ), 
    private=list(
     a=NA, 
     ifunc=ifunc 
    ) 
) 

但是,我必須說,我不明白這個策略。函數funcifunc然後在頂級環境中都有自己的名字,但是不起作用 - 它們在類定義中只是有意義的。如果代碼重用是你感興趣的東西,我認爲對象組合或繼承將不太令人驚訝。

+0

我認爲包和roo原包將支持你想要的東西:你不必定義類中的所有成員def從頭。但是可能你會失去一些你喜歡R6的功能...... – Sebastian

1

首先,讓我們熬的例子下來,使其更說:

# function defined outside R6 class 
parent_function <- function(x) { 
    if (missing(x)) { 
    child_function() 
    } else { 
    self$a <- x * x 
    } 
} 

# function called by previous function 
child_function <- function() { 
    self$a <- 999999 
} 

# R6 test object 
my_object <- R6::R6Class(
    "my_object", 
    public=list(
    func=parent_function, 
    a=1 
) 
) 


# Testing 
tst <- my_object$new() 
tst 

## <my_object> 
## Public: 
## a: 1 
## clone: function (deep = FALSE) 
## func: function (x) 


tst$func(8) 
tst$a 

## [1] 64 


tst$func() 

## Error in self$a <- 999999 : object 'self' not found 

現在的想法是傳下來self孩子功能 - 因爲父功能,可以很明顯的看出自我,所以它可以通過它

# General function defined outside R6 class 
parent_function <- function(x) { 
    if (missing(x)) { 
    child_function(self) 
    } else { 
    self$a <- x * x 
    } 
} 

# If interactive, redirect to this function 
child_function <- function(self) { 
    self$a <- 999999 
} 

# R6 test object 
my_object <- R6::R6Class(
    "my_object", 
    public = 
    list(
     func=parent_function, 
     a=1 
    ), 
) 

## Testing 
tst <- my_object$new() 
tst 

## <my_object> 
## Public: 
## a: 1 
## clone: function (deep = FALSE) 
## func: function (x) 


tst$func(8) 
tst$a 

## [1] 64 


tst$func() 
tst$a 

## [1] 999999 
相關問題