2012-09-22 3 views
7

현재 참조 클래스를 사용하여 패키지를 작성 중입니다. 참조 방법은 모든 모든 복사하지 않기 때문에 나는 발생 수집 참조 클래스, 탭 완성 및 강제 메서드 정의

Can't reliably use RefClass methods in Snowfall

는 그들이 오히려 수업 시간에 객체

Method initialisation in R reference classes

: I는 다양한 소스를 읽고 문제가 건너왔다 처음 액세스 할 때 복사됩니다.

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

example <- test$new() 

을 그래서 예는 클래스 TEST의 새로운 오브젝트입니다 : 예를 들어

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

정의. example$를 입력하고 콘솔에서 탭 이동하는
> example$ 
# example$.->a   example$.refClassDef example$.self   
# example$a   example$initialize 

그래서 방법 addone가 옵션으로 제공되지 수 있습니다. 그것은 그러나 전화로 볼 수 있습니다 :

example$addone() 

지금 탭 이동을 다시 그래서 지금 addonefieldshow가 옵션으로 제공됩니다

# > 
# > 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 

을 보여준다.

마틴 모건 (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으로보다 우아하게 처리됩니다.지속적인 해킹 그래서 어쩌면 S3 방법이에 대한 클래스 계층의 기지에 기록 될 수

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

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

탭 완료가 utils 패키지에 .DollarNames을 통해 사용자 정의 할 수 있습니다, 될 수 있을까요?

+0

내 솔루션보다 매우 유용하고 우아합니다. 또한 나는 그것이 탭 완료라고 이름이 지어진다라는 것을 모르고 있었다. 이 용어를 알면 나는 utils에서 관련 패키지를 찾을 수있었습니다. 참조 클래스를 사용한 탭 완성은 내 목표 였고 이것을 더 잘 반영하기 위해 질문 제목을 편집합니다. – jdharrison

+0

이것은 매우 유망한 것처럼 보입니다. '.DollarNames.envRefClass <- function (x, pattern) grep (패턴, getRefClass (클래스 (x)) $ methods(), value = TRUE)'를 내 패키지에 추가하는 것은 나쁜 생각일까요? – jdharrison

+0

네, 단지 자신의 것이 아닌 모든 참조 클래스의 동작을 변경하는 것이 좋지 않을 것입니다. 어쩌면 현재의 행동과 같을 것입니다. 아마도'methods'는 장래에'.DollarNames.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

나는이 오래된 질문이지만, 구글에 refClass 탭 완료를 검색 할 때 여전히 최상위 항목 알고, 그래서 난 그냥 업데이 트를 추가 할 것입니다 :

대신에 GREP을 사용. 마틴에 의해 제안 DollarNames 기능으로, 더 나은 다른 Rgui의 주위에 재생 될 때 유틸 패키지에서 사용 findMatches는

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

이 탭 완료가 내부적으로 처리하는 방법도있다 (그렙 타격 탭에 따라 당신의 부분적으로 입력 한 이름을 삭제합니다) 목록 및 데이터 용. 프레임