Programowanie obiektowe w taki czy inny sposób jest bardzo możliwe w R.Jednak w przeciwieństwie do na przykład Pythona, istnieje wiele sposobów osiągnięcia orientacji obiektowej:
- Pakiet R.oo
- Klasy S3 i S4
- Klasy referencyjne
- pakiet proto
Moje pytanie brzmi:
Jakie główne różnice odróżniają te sposoby programowania obiektowego w R?
Idealnie byłoby, gdyby odpowiedzi tutaj posłużyły jako odniesienie dla programistów R próbujących zdecydować, które metody programowania obiektowego najlepiej odpowiadają ich potrzebom.
W związku z tym proszę o szczegóły, przedstawione w sposób obiektywny, oparty na doświadczeniu, poparty faktami i referencjami. Dodatkowe punkty za wyjaśnienie, w jaki sposób te metody odpowiadają standardowym praktykom OO.
Odpowiedzi:
Klasy S3
print
wywołańprint.lm
print.anova
itp. A jeśli nie zostanie znaleziona,print.default
Klasy S4
Klasy referencyjne
proto
Klasy R6
źródło
library("fortunes"); fortune("strait")
Edytuj w dniu 08.03.12: Poniższa odpowiedź odpowiada na część pierwotnie opublikowanego pytania, które zostało usunięte. Skopiowałem to poniżej, aby podać kontekst mojej odpowiedzi:
Mój wkład dotyczy twojego drugiego pytania, w jaki sposób metody OO R są mapowane na bardziej standardowe metody OO. Kiedy myślałem o tym w przeszłości, wracałem raz po raz do dwóch fragmentów, jednego autorstwa Friedricha Leischa, a drugiego Johna Chambersa. Oba wykonują dobrą robotę, wyjaśniając, dlaczego programowanie w stylu OO w R ma inny smak niż w wielu innych językach.
Najpierw Friedrich Leisch z „Tworzenie pakietów języka R: samouczek” ( ostrzeżenie: PDF ):
Drugi fragment pochodzi ze znakomitej książki Johna Chambersa „Oprogramowanie do analizy danych” . ( Link do cytowanego fragmentu ):
źródło
S3 i S4 wydają się być oficjalnymi (tj. Wbudowanymi) podejściami do programowania obiektowego. Zacząłem używać kombinacji S3 z funkcjami osadzonymi w funkcji / metodzie konstruktora. Moim celem było uzyskanie składni typu object $ method (), tak aby mieć półprywatne pola. Mówię półprywatne, ponieważ nie da się ich tak naprawdę ukryć (o ile wiem). Oto prosty przykład, który tak naprawdę nic nie robi:
#' Constructor 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)) ) #Add a few more methods 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) } #' Define S3 generic method for the print function. print.EmailClass <- function(x) { if(class(x) != "EmailClass") stop(); cat(paste(x$get("name"), "'s email address is ", x$get("email"), sep='')) }
I trochę kodu testowego:
test <- EmailClass(name="Jason", "[email protected]") 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("[email protected]") test$getHistory() test$sendMail("[email protected]") test$getNumMessagesSent() test2 <- EmailClass("Nobody", "[email protected]") test2 test2$props test2$getHistory() test2$sendMail('[email protected]')
Oto link do wpisu na blogu, który napisałem o tym podejściu: http://bryer.org/2012/object-oriented-programming-in-r Z zadowoleniem przyjmuję komentarze, krytykę i sugestie dotyczące tego podejścia, ponieważ nie jestem przekonany siebie, jeśli to najlepsze podejście. Jednak problem, który próbowałem rozwiązać, działał świetnie. W szczególności w przypadku pakietu makeR ( http://jbryer.github.com/makeR ) nie chciałem, aby użytkownicy bezpośrednio zmieniali pola danych, ponieważ potrzebowałem upewnić się, że plik XML reprezentujący stan mojego obiektu pozostanie zsynchronizowany. Działało to doskonale, o ile użytkownicy przestrzegali zasad, które zarysowałem w dokumentacji.
źródło