2017-07-26 79 views
1

我來自C++背景,試圖利用它來進行R6包的R OOP編程。
在編寫大型OOP代碼時,請考慮以下典型情況。 - 你有一個類,其中你有幾個(可能很多)的功能,其中的每一個也可能是相當複雜,與很多行代碼:是否可以更改R6功能的值? (良好風格的OOP編程?)

# file CTest.R 

cTest <- R6Class(
    "CTest", 
    public = list(
    z = 10, 
    fDo1 = function() { 
     # very long and complex code goes here 
     self$z <- self$z*2; self$z 
     }, 
    fDo2 = function() { 
     # another very long and complex code goes here 
    print(self) 
    } 
) 
) #"CTest" 

當然,你不想把所有您的長期和各種功能(CTest.R)文件 - 它會變得凌亂和無法管理。
如果你使用C++編程,正常的編程方式是:首先,你在.h文件中聲明你的函數,然後爲你定義函數的每個複雜函數創建.c文件。這使得協作代碼編寫成爲可能,包括高效的源代碼控制。因此,我試圖在R中做類似的事情,比如:首先,在上面的代碼中聲明一個函數,然後嘗試將「實際的長和複雜的」代碼稍後分配給它(稍後我將放在一個單獨的文件CTest-Do1.R):

cTest$f <- function() {  
    self$z <- self$z*100000; self$z 
} 

現在我測試,如果它的工作原理:

> tt <- cTest$new(); tt; tt$fDo1(); tt 
<CTest> 
Public: 
clone: function (deep = FALSE) 
fDo1: function() 
fDo2: function() 
z: 10 
[1] 20 
<CTest> 
Public: 
clone: function (deep = FALSE) 
fDo1: function() 
fDo2: function() 
z: 20 

不,它not.-從上面的輸出可見,功能尚未改變。

有什麼建議嗎?

+1

請參閱https://stackoverflow.com/questions/26331030/dynamically-add-function-to-r6-class-instance –

+1

「如果您使用C++(Java等)進行編程,則編寫此類代碼的正常方法是:首先,你在.h文件中聲明你的函數,然後你爲你的每個複雜函數創建.c文件,在那裏定義你的函數「 - 這實際上並不適用於Java。對於具有單獨的頭文件和實現文件的語言而言,這並不常見。 – user2357112

回答

1

感謝上面的格洛騰迪克的評論,有一個合理的解決方法,使其工作。

取而代之的是:

# CTest-Do1_doesnotwork.R 
cTest$fDo1 <- function() { 
    ... 
}  

這樣寫:

# CTest-Do1_works.R 
cTest$set(
    overwrite = TRUE, "public", "fDo1",  
    function() { 
     ... 
    } 
) 

該代碼可以寫在單獨的文件,如最初期望。

我還在想 - 雖然上面描述的方式實際上是在R社區編寫大型OOP代碼的常見(最佳)做法嗎? (對我來說看起來有點奇怪)。
如果不是,它是什麼(除了只使用source())? - 以便爲類的單獨部分(功能)啓用協作編碼和源代碼控制?

1

我來這裏也在尋找R6的最佳做法。我見過的一種方式(here)是在別處定義功能正常R裏面的函數,並通過自我,私營等要求

cTest<- R6::R6Class("CTest", 
    public = list(

    fDo1 = function() 
    cTestfDo1(self), 

    fDo2 = function(x) 
    cTestfDo2(self, private, x) 
)) 

和其他地方有

cTestfDo1 <- function(self) { 
    self$z <- self$z*2; self$z 
} 

和其他地方

cTestfDo2 <- function(self, private, x) { 
    self$z * private$q + x 
} 

我不知道這是否是最好的公關actice或高效的,但類定義看起來很整潔,如果cTestfDo1函數沒有導出,那麼它在命名空間中也相對整潔。

+0

Gabor的另一個例子https://github.com/r-lib/processx/blob/master/R/process.R – dougmet