2012-11-09 4 views
2

저는 R 's R5 클래스 시스템으로 할 수 있고 할 수없는 것을보기 위해 조금 놀았습니다.참조 클래스 - 정적 필드 멤버/변수가 있습니까?

[2014 업데이 트]
경고! - 그 과정에서 나는 정적 클래스 필드 멤버의 모습을 우연히 발견했다 (하지만 난 그것을 놓쳤을 수있는 문서로 표시되지 않음) : 다음 코드는 R 버전> = 3.0과 호환되지 않습니다.
이 게시물, 답변 및 특히 주석은 R5 OO 시스템 및 R 언어에 대한 유용한 통찰력과 알림을 제공합니다. 그러나 R5 클래스 인스턴스의 환경을 직접 사용하는 관용구를 직접 개발하는 것은 나쁜 생각 일 수 있습니다.
[END 업데이트 2014] 다음 코드

는 제 필드는 인스턴스 필드 변수의 고전적인 정의이다. 두 번째 정의는 접근 자 메서드를 사용하여 정적 클래스 필드를 만드는 것으로 나타납니다. 이 사용이 정결한지 알고 싶습니다 (또는 내 코드 예제는 단순히 우연입니다). 세 번째 필드 사용은 액세서 메소드를 사용하여 준 개인 인스턴트 필드 변수를 만듭니다.

assertClass <- function(x, className, R5check=FALSE) { 
    # simple utility function 
    stopifnot(class(x)[1] == className) 
    if(R5check) stopifnot(is(x, 'envRefClass')) 
} 

A <- setRefClass('A', 
    fields = list(
     # 1. public, typed, instance field 
     myPublicInstanceVar = 'character', 

     # 2. this assignment appears static 
     # but if the field me.static.private 
     # was declared in the field list 
     # it would be a local instance var 
     myPrivateStaticVar = function(x) { 
      if (!missing(x)) { 
       assertClass(x, 'character') 
       me.static.private <<- x 
      } 
      me.static.private 
     }, 

     # 3. quasi-private, typed, instance field 
     myPrivateInstanceVar = function(x) { 
      if (!missing(x)) { 
       assertClass(x, 'character') 
       .self$me.private <<- x 
      } 
      .self$me.private 
     } 
    ), 

    methods = list(
     initialize = function (c='default') { 
      myPublicInstanceVar <<- c 
      myPrivateStaticVar <<- c 
      myPrivateInstanceVar <<- c 
     } 
    ) 
) 

# test instantiation 
instance1.of.A <- A$new('first instance') 
str(instance1.of.A) 

instance2.of.A <- A$new('second instance') 
str(instance1.of.A) 
str(instance2.of.A) 

instance3.of.A <- getRefClass('A')$new('third instance') 
instance3.of.A$myPrivateStaticVar <- 'Third instance - changed' 
print(instance1.of.A$myPrivateStaticVar) 
print(instance2.of.A$myPrivateStaticVar) 
print(instance3.of.A$myPrivateStaticVar) 
str(instance1.of.A) 
str(instance2.of.A) 
str(instance3.of.A) 

# but not really private ... 
instance1.of.A$myPublicInstanceVar # works 
instance1.of.A$me.static.private # DOES NOT WORK - where is this variable stored 
instance1.of.A$me.private   # works 

# till death do us part 
instance3.of.A <- NULL 
gc() 
str(instance1.of.A) 
str(instance2.of.A) 
str(instance3.of.A) 

이 코드를 실행하면 두 번째 필드 변수가 정적 클래스 멤버로 작동하는 것으로 나타납니다. 나에게 덜 명확한 것은 참조 클래스가이 필드를 유지하는 부분입니다 (그러므로 위에서 두 번째 줄의 주석).

+0

2. 전혀 이상하게 보이거나 이상한 것 같지 않습니다 - 표준 R 환경 의미입니다. 하지만 나는 여러분이 지구 환경에서'me.static.private'를 할당했기 때문에 여러분이 무슨 일이 일어나고 있는지 오해한다고 생각합니다. – hadley

+1

그리고 3. 나는'<< -'가 필요하다고 생각하지 않습니다. 지정된 환경'.self' 지정된 변수'.self' – hadley

+0

해들리 - 당신의 통찰력에 다시 한번 감사드립니다. # 2 당신 말이 맞습니다. 'me.static.private' 변수는 지구 환경에 있습니다. # 3에서 ls()를 사용하여 볼 수 있습니다. '<< -'와'<-'는 같은 장소에 쓰지만 (확실하지는 않습니다), 내 테스트는 이것을 나타냅니다. 서브 클래스에서는 다른 결과가 발생합니다). –

답변

1

위의 해들리의 의견을 바탕으로 짧은 대답이 '아니오'입니다. R의 참조 클래스에는 정적 변수가 없습니다.