2012-09-22 15 views
7

現在、参照クラスを使用してパッケージを作成しています。それらは、参照メソッドは、むしろ、クラス内のすべてのオブジェクト にコピーされ、すべてのされていないので、私が集まる参照クラス、タブ補完および強制メソッド定義

Method initialisation in R reference classes

Can't reliably use RefClass methods in Snowfall

原因です:私は、さまざまなソースを読んでから問題が に遭遇してきました最初にアクセスしたときにコピーされます。一例として、

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$を入力して コンソールにタブ移動すると、その方法addoneがオプションとして提示されていない

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

を与えます。それはしかし、 コールに提供されています:今、再びタブ移動

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 

addonefieldshowが選択肢として提示されている明らかにする。

Martin Morganは、上記のリンクのいずれかでメソッドを強制的に定義することを推奨しています。この 作品はよく

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 

私のクラスのいくつかは、私はとしてsuccintly可能な限りこれをやりたい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([email protected])))) 
              } 
          ) 
       ) 

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  

これは、それは少し不器用な感じに動作なくなり。また[email protected]が使用され、が少し間違っていると感じるので、getRefClass("TEST")[email protected]ではなくむしろ使用されます。これまで誰もこの問題を扱っていませんか?

ソリューションにアプローチするより良い方法はありますか?質問が過度に引き出された場合は、アドバイスやお詫び申し上げます。

答えて

6

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

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

タブ補完はutilsパッケージに.DollarNamesを経由してカスタマイズすることができるかもしれないので、

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

はたぶんS3メソッドは、このために、あなたのクラス階層のベースに書かれるだろうか?

+0

ありがとうございました。私のソリューションよりも非常に有益であり、よりエレガントです。また、私はそれがタブ補完と呼ばれていたことを知りませんでした。この用語を知ることで、私はutilsの関連パッケージを見つけることができました。参照クラスによるタブ補完は私の目的でした。これをよりよく反映するように質問タイトルを編集します。 – jdharrison

+0

これは非常に有望なようです。 '.DollarNames.envRefClass < - function(x、pattern)grep(パターン、getRefClass(クラス)(x))$ methods()、value = TRUE)'を私のパッケージに追加するのは悪い考えですか? – jdharrison

+0

はい、あなたのものだけでなく、すべての参照クラスの振る舞いを変えることは悪い考えです。多分現在の動作のようなものかもしれませんが、おそらく 'メソッド'は将来的には 'DameNames.envRefClass'を実装し、あなたの長い忘れたメソッドはこれをオーバーライドします。適切なことは、R-develを機能要求として呼び出すことです。特に、適切と思われる動作を説明するためのプロトタイプが少なくとも必要です。 –

1

@ Martin Morganは、これをタブ補完と称した。パッケージrcompletionおよびそれ以降のrcompgenはこれを達成することを任されました。彼らはutilsに移動しました。

rcompletion update

私はcompletion.Rのために、私はutils:::.DollarNames.environmentは、参照クラスのタブ補完を処理していた決定ができ​​るものからコードを通して見えました。

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

いくつかの点に注意する:私は私自身の使用のためにこれを使用する

  • 機能を再定義

    completion.R

    は、タブ補完を実現するように見えました。現在、私はデバッグしてパッケージを文書化しています。私はいくつかの長いメソッド名を持っていたので、タブの補完が大いに役立つので、正確に何かを覚えていませんでした。

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

  • メソッドの強制的な定義が推奨されます。

+0

実際には、 '.DollarNames'はS3汎用メソッドなので、S3メソッドを書くことができます。私はこれを私の答えに描いた。 –

3

は、私は、これは古い質問ですが、GoogleのrefClassのタブ補完を検索するとき、それはまだトップエントリである知っているので、私はちょうど更新を追加します:

代わりにはgrepを使用します。それは異なるRguiの周りで、より良い果たしているとマーティンによって提案されDollarNames機能は、これはタブ補完が内部的に処理する方法もある

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

(grepのタブを打つ時に、あなたの部分的に入力した名前を削除します)utilsのパッケージからfindMatchesを使用しますリストとデータのためのフレーム。

関連する問題