Я узнал об этом в программе Johns Hopkins MOOC R давным-давно на Coursera.Идея состояла в том, чтобы вернуть список функций, которые были определены в области действия родительской функции.Например:
newString <- function(s) {
l <- nchar(s)
return(list(
get = function() return(s),
len = function() return(l),
concate = function(cat) {
s <<- paste0(s, cat)
l <<- nchar(s)
},
find = function(pattern) return(grepl(pattern, s)),
substitute = function(pattern, sub) {
s <<- gsub(pattern, sub, s)
l <<- nchar(s)
}
))
}
Эта функция возвращает список функций / методов, которые могут манипулировать элементом "s".Я могу «новый» этот «объект», вызывая функцию отца:
my <- newString("hellow")
И использование «методов» с $
просто выглядит как ООП.
my$get()
# [1] "hellow"
my$len()
# [1] 6
my$substitute("w$", "")
my$get()
# [1] "hello"
my$len()
# [1] 5
my$concate(", world")
my$get()
# [1] "hello, world"
my$find("world$")
# [1] TRUE
Чтобы напечатать«объект» напрямую, мы можем видеть, что это список функций.И все эти функции находятся в той же среде 0x103ca6e08
, где также находился элемент s
.
my
# $get
# function ()
# return(s)
# <bytecode: 0x1099ac1e0>
# <environment: 0x103ca6e08>
#
# $len
# function ()
# return(l)
# <bytecode: 0x109a58058>
# <environment: 0x103ca6e08>
#
# $concate
# function (cat)
# {
# s <<- paste0(s, cat)
# l <<- nchar(s)
# }
# <bytecode: 0x1074fd4e8>
# <environment: 0x103ca6e08>
#
# $find
# function (pattern)
# return(grepl(pattern, s))
# <bytecode: 0x1076c8470>
# <environment: 0x103ca6e08>
#
# $substitute
# function (pattern, sub)
# {
# s <<- gsub(pattern, sub, s)
# l <<- nchar(s)
# }
# <bytecode: 0x1077ad270>
# <environment: 0x103ca6e08>
Так считается ли этот стиль программирования (?) ООП или ООП-подобным?Чем это отличается от S3 / S4?
Благодаря @ G.Grothendieck, @ r2evans и @Jozef.Демонстрационная документация для scoping
в R говорит, что «функции могут инкапсулировать информацию о состоянии» из-за правил области видимости в R. И система RC «использует среду», поэтому я думаю, что то, что я сделал, было похоже на примитивную систему RC.
"Объект - это данные с функциями. Закрытие - это функция с данными."- Джон Д. Кук
Закрытия получают свое имя, потому что они включают среду родительской функции и могут обращаться ко всем ее переменным.
В http://adv -r.had.co.nz / Functional-software.html # closures Я нашел наиболее подходящее имя для этого - closure .