7

私は現在、参照クラスを使用してパッケージを作成しています。私はさまざまな情報源を読んだことから問題に遭遇しました:

R参照クラスでのメソッドの初期化

SnowfallでRefClassメソッドを確実に使用できない

私が収集するのは、参照メソッドがクラス内のすべてのオブジェクトにすべてコピーされるのではなく、最初にアクセスされたときにコピーされるためです。

https://stat.ethz.ch/pipermail/r-devel/2011-June/061261.html

例として、以下を定義します。

test <- setRefClass("TEST",
                fields = list( a = "numeric"),
                methods = list(
                   addone = function(){
                                        a <<- a+1
                                      },
                   initialize = function(){
                                            a <<- 1
                                          }
                              )
               )

example <- test$new()

したがって、例はクラスの新しいオブジェクトですTEST。コンソールで入力example$してタブを押すと、

> example$
# example$.->a         example$.refClassDef example$.self        
# example$a            example$initialize 

そのため、この方法addoneはオプションとして提示されていません。ただし、電話をかけることができます。

example$addone()

今度はタブでもう一度表示します

# > 
# > example
# Reference class object of class "TEST"
# Field "a":
# [1] 2
# > example$
# example$.->a         example$.refClassDef example$.self        
# example$a            example$addone       example$field        
# example$initialize   example$show

だから今addoneそしてfieldそしてshowオプションとして提示されています。

Martin Morganは、上記のリンクの1つでメソッドの定義を強制することをお勧めします。これはうまくいきます

test <- setRefClass("TEST",
                fields = list( a = "numeric"),
                methods = list(
                   addone = function(){
                                        a <<- a+1
                                      },
                   initialize = function(){
                                            a <<- 1
                                            .self$addone #force definition
                                          }
                              )
               )

example <- test$new()

だから今タブは与える:

# > example$
# example$.->a         example$.refClassDef example$.self        
# example$a            example$addone       example$initialize  

私のクラスのいくつかは30以上のメソッドを持っているので、これをできるだけ簡潔にしたいと思います。私は定義しました:

test <- setRefClass("TEST",
                fields = list( a = "numeric"),
                methods = list(
                   addone = function(){
                                        a <<- a+1
                                      },
                   initialize = function(){
                      a <<- 1
                      eval(parse(text=paste0('.self$',ls(test$def@refMethods))))
                                          }
                              )
               )

example <- test$new()

タブを使用すると、次のようになります。

# > example$
# example$.->a         example$.refClassDef example$.self        
# example$a            example$addone       example$callSuper    
# example$copy         example$export       example$field        
# example$getClass     example$getRefClass  example$import       
# example$initFields   example$initialize   example$show         
# example$trace        example$untrace     

これは機能しますが、少し不器用に感じます。また、それは少し間違っていると感じるようにではtest$def@refMethodsなく使用されます。getRefClass("TEST")$def@refMethods誰かが以前にこの問題に対処したことがあります。

解決策にアプローチするためのより良い方法はありますか?質問が過度に引き出された場合は、アドバイスと謝罪に感謝します。

4

3 に答える 3

6

あなたの目的は何ですか?タブ補完で表示される関数名?次に、機能リクエストを添えてR-develメーリングリストに投稿する価値があります。元のシナリオは、に記載されているように、よりエレガントに処理さusingMethodsれます?setRefClass。継続的なハッキングは

initialize = function(...) {
    methods <- getRefClass(class(.self))$methods()
    eval(parse(text=paste0(".self$", methods)))
    callSuper(...)
}

タブの補完.DollarNamesutilsパッケージ内でカスタマイズできるため、

.DollarNames.TEST <- function(x, pattern)
    grep(pattern, getRefClass(class(x))$methods(), value=TRUE)

たぶん、このためにクラス階層のベースにS3メソッドを書くことができますか?

于 2012-09-22T15:59:35.900 に答える
3

これは古い質問ですが、GoogleでrefClassタブ補完を検索するときのトップエントリなので、更新を追加します。

Martinが提案したように.DollarNames関数でgrepを使用する代わりに、utilsパッケージのfindMatchesを使用します。これは、さまざまなRguiの周りでより適切に機能するためです(grepは、タブを押すと部​​分的に入力された名前を削除します)

.DollarNames.TEST <- function(x, pattern){
    utils:::findMatches(pattern, getRefClass(class(x))$methods())
}

これは、リストとdata.framesのタブ補完が内部的に処理される方法でもあります。

于 2014-11-03T09:50:38.840 に答える
1

@Martin Morganは、これはタブ補完と呼ばれると述べました。パッケージrcompletion以降rcompgenは、これを達成するという任務を負っていました。現在、に移動されていutilsます。

rcompletionアップデート

コードを調べて、参照クラスのタブ補完を処理completion.Rしていると判断できました。utils:::.DollarNames.environment

完了.R

関数を再定義すると、タブ補完が達成されたようです。

assignInNamespace( x = ".DollarNames.environment",
                     function(x, pattern = "") {
    y <- NULL
    if(isS4(x) && !is.null(x[['.refClassDef']])){
      if(.hasSlot(x$.refClassDef,'refMethods')){
        y<-x$.refClassDef@refMethods
        y<-ls(y, all.names = TRUE, pattern = pattern)
      }
    }
    x<-ls(x, all.names = TRUE, pattern = pattern)
    unique(c(x,y))
                                               }
,ns = "utils")

注意すべき点:

  • 私はこれを自分の用途にのみ使用します。現在、パッケージのデバッグと文書化を行っています。私はいくつかの長いメソッド名を持っていて、それらが何であるかを正確に思い出せなかったので、タブ補完が大いに役立ちます。

  • パッケージ内での使用はassignInNamespace(禁止されていない場合)拒否されます。を参照してください?assignInNamespace

  • メソッドを強制的に定義することをお勧めします。

于 2012-09-23T01:51:46.840 に答える