R и объектно-ориентированное программирование
объектно-ориентированное программирование так или иначе очень возможно в R. Однако, в отличие от, например, Python, существует много способов достижения объектной ориентации:
- The R. OO package
- S3 и S4 классы
- ссылка на классы
- the прото пакет
мой вопрос:
Что майор различия различают эти способы ОО программирования в R?
В идеале ответы здесь будут служить ссылкой для программистов R, пытающихся решить, какие методы программирования OO лучше всего подходят для их потребностей.
Как таковой, я прошу подробностей, представленных объективным образом, основанных на опыте и подкрепленных фактами и ссылками. Бонусные баллы за уточнение как эти методы сопоставляются со стандартными практиками OO.
3 ответов:
классы S3
- не совсем объекты, скорее соглашение об именах
- судя по всему . синтаксис: например, для печати,
print.lmprint.anovaи т. д. А если не нашли, тоprint.defaultS4 классы
- может отправлять по нескольким аргументам
- сложнее реализовать, чем S3
ссылка классы
- в первую очередь полезно, чтобы избежать копирования больших объектов (пройти по ссылке)
- описание причин использования Рефклассов
прото
- ggplot2 первоначально был написан в proto, но в конечном итоге будет переписан с использованием S3.
- аккуратная концепция (прототипы, а не классы), но кажется сложным на практике
- следующая версия ggplot2, кажется, будет отойдя от него
- описание концепции и реализации
R6 классы
изменить на 3/8/12: ответ ниже отвечает на часть первоначально опубликованного вопроса, который с тех пор был удален. Я скопировал его ниже, чтобы обеспечить контекст для моего ответа:
Как различные методы OO сопоставляются с более стандартными методами OO, используемыми, например, в Java или Python?
мой вклад относится к вашему второму вопросу о том, как методы R OO сопоставляются с более стандартными методами OO. Как я уже думал об этом в в прошлом я снова и снова возвращался к двум отрывкам, один из которых принадлежит Фридриху Лейшу, а другой-Джону Чемберсу. Оба хорошо понимают, почему OO-подобное программирование в R имеет другой вкус, чем во многих других языках.
во-первых, Фридрих Лейш, из "создание пакетов R: учебник" (внимание: PDF):
S редко, потому что он является интерактивным и имеет систему для объектной ориентации. Проектирование классов явно является программированием, тем не менее, чтобы сделать s полезным в качестве интерактивной среды анализа данных, имеет смысл, что это функциональный язык. В" реальных " языках объектно-ориентированного программирования (ООП), таких как C++ или Java, определения классов и методов тесно связаны друг с другом, методы являются частью классов (и, следовательно, объектов). Нам нужны инкрементные и интерактивные дополнения, такие как пользовательские методы для предопределенных классов. Эти дополнения могут быть сделаны в любой момент времени, даже на лету в командной строке, пока мы анализ набора данных. S пытается найти компромисс между объектной ориентацией и интерактивным использованием, и хотя компромиссы никогда не являются оптимальными по отношению ко всем целям, которые они пытаются достичь, они часто работают на удивление хорошо на практике.
другой отрывок взят из великолепной книги Джона Чемберса "программное обеспечение для анализа данных". (ссылка на цитируемый отрывок):
модель программирования ООП отличается от языка S во всем, кроме первый точка, хотя S и некоторые другие функциональные языки поддерживают классы и методы. Определения методов в системе ООП являются локальными для класса; не требуется, чтобы одно и то же имя для метода означало одно и то же вещь для несвязанного класса. Напротив, определения методов в R не делают находятся в определении класса; концептуально они связаны с общим функция. Определения классов введите в определение выбора метода, непосредственно или через наследование. Программисты, используемые в модели ООП, иногда расстроен или смущен тем, что их программирование не передается на R напрямую, но это невозможно. Функциональное использование методов, является более сложным, но и более настроенный на наличие значимых функций, и не может быть сведен к Версия ООП.
S3 и S4, похоже, являются официальными (т. е. встроенными) подходами для программирования OO. Я начал использовать комбинацию S3 с функциями, встроенными в функцию/метод конструктора. Моя цель состояла в том, чтобы иметь синтаксис типа object$method (), чтобы у меня были полу-частные поля. Я говорю полу-частный, потому что нет никакого способа действительно скрыть их (насколько я знаю). Вот простой пример, который на самом деле ничего не делает:
#' 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='')) }и некоторые тестовый код:
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]')здесь ссылка на сообщение в блоге я написал об этом подходе:http://bryer.org/2012/object-oriented-programming-in-r я приветствую комментарии, критику и предложения к этому подходу, поскольку я не уверен, что это лучший подход. Однако для проблемы, которую я пытался решить, она отлично сработала. В частности, для пакета производителя (http://jbryer.github.com/makeR) я не хотел, чтобы пользователи меняли поля данных напрямую, потому что мне нужно было убедиться, что XML файл, который представлял состояние моего объекта будет оставаться в синхронизации. Это отлично работало до тех пор, пока пользователи придерживались правил, которые я описываю в документации.
Comments