S3 및 S4는 OO 프로그래밍을위한 공식 (즉, 내장) 접근 방식 인 것 같습니다. S3와 생성자 함수 / 메서드에 포함 된 함수의 조합을 사용하기 시작했습니다. 내 목표는 object $ method () 유형 구문을 사용하여 반 개인 필드를 갖는 것입니다. 나는 그들을 정말로 숨길 방법이 없기 때문에 (내가 아는 한) 반 비공개라고 말합니다. 다음은 실제로 아무것도하지 않는 간단한 예입니다.
EmailClass <- function(name, email) {
nc = list(
name = name,
email = email,
get = function(x) nc[[x]],
set = function(x, value) nc[[x]] <<- value,
props = list(),
history = list(),
getHistory = function() return(nc$history),
getNumMessagesSent = function() return(length(nc$history))
)
nc$sendMail = function(to) {
cat(paste("Sending mail to", to, 'from', nc$email))
h <- nc$history
h[[(length(h)+1)]] <- list(to=to, timestamp=Sys.time())
assign('history', h, envir=nc)
}
nc$addProp = function(name, value) {
p <- nc$props
p[[name]] <- value
assign('props', p, envir=nc)
}
nc <- list2env(nc)
class(nc) <- "EmailClass"
return(nc)
}
print.EmailClass <- function(x) {
if(class(x) != "EmailClass") stop();
cat(paste(x$get("name"), "'s email address is ", x$get("email"), sep=''))
}
그리고 일부 테스트 코드 :
test <- EmailClass(name="Jason", "jason@bryer.org")
test$addProp('hello', 'world')
test$props
test
class(test)
str(test)
test$get("name")
test$get("email")
test$set("name", "Heather")
test$get("name")
test
test$sendMail("jbryer@excelsior.edu")
test$getHistory()
test$sendMail("test@domain.edu")
test$getNumMessagesSent()
test2 <- EmailClass("Nobody", "dontemailme@nowhere.com")
test2
test2$props
test2$getHistory()
test2$sendMail('nobody@exclesior.edu')
다음은이 접근 방식에 대해 작성한 블로그 게시물에 대한 링크입니다. http://bryer.org/2012/object-oriented-programming-in-r 이 접근 방식 에 대한 의견, 비판 및 제안을 환영합니다. 이것이 최선의 방법이라면 나 자신. 그러나 내가 해결하려고 노력한 문제는 훌륭하게 작동했습니다. 특히 makeR 패키지 ( http://jbryer.github.com/makeR )의 경우 내 개체의 상태를 나타내는 XML 파일이 동기화 상태를 유지해야했기 때문에 사용자가 데이터 필드를 직접 변경하는 것을 원하지 않았습니다. 사용자가 문서에 설명 된 규칙을 준수하는 한 완벽하게 작동했습니다.