parLapply в классах R6

Я ищу использовать parLapply() на окнах в пределах R6 возразил и заметил (что по крайней мере в некоторых случаях), что мне не нужно экспортировать функции или данные R6 в узлы.

Вот пример, где я могу получить доступ к закрытым методам внутри parLapply():

require(R6);require(parallel)
square <-
R6Class("square",
        public = list(
            numbers = NA,
            squares = NA,
            initialize = function(numbers,integer) {
                self$numbers <- numbers
                squares <- private$square.numbers()
            }
        ),
        private = list(
            square = function(x) {
                return(x^2)
            },
            square.numbers = function() {
                cl <- makeCluster(detectCores())
                self$squares <- parLapply(cl,
                                          self$numbers,
                                          function (x) private$square(x)
                                          )
                stopCluster(cl)
            }
        ))
##Test
test <- square$new(list(1,2,3))
print(test$squares)
# [[1]]
# [1] 1
# 
# [[2]]
# [1] 4
# 
# [[3]]
# [1] 9

И второй пример, где я также могу получить доступ к публичным членам:

square2 <-
R6Class("square2",
        public = list(
            numbers = NA,
            squares = NA,
            integer = NA,
            initialize = function(numbers,integer) {
                self$numbers <- numbers
                self$integer <- integer
                squares <- private$square.numbers()
            }
        ),
        private = list(
            square = function(x) {
                return(x^2)
            },
            square.numbers = function() {
                cl <- makeCluster(detectCores())
                self$squares <- parLapply(cl,
                                          self$numbers,
                                          function (x) private$square(x)+self$integer
                                          )
                stopCluster(cl)
            }
        ))
##Test
test2 <- square2$new(list(1,2,3),2)
print(test2$squares)
#[[1]]
#[1] 3
#
#[[2]]
#[1] 6
#
#[[3]]
#[1] 11

У меня двоякий вопрос: (1) Что с R6 делает это возможным, так что мне не нужно экспортировать объекты данных и функции; и (2) я могу положиться на это поведение или это артефакт этих конкретных примеров?

ОБНОВИТЬ:

Это поведение также работает с использованием открытых методов и членов после создания экземпляра объекта:

square3 <- R6Class(
    classname = "square3",
    public = list(
        numbers = NA,
        squares = NA,
        integer = NA,
        square = function(x) {
           return(x^2)
        },
        square.numbers = function() {
            cl <- makeCluster(detectCores())
            self$squares <- parLapply(cl,
                                      self$numbers,
                                   function (x) self$square(x)+self$integer
                                  )
        stopCluster(cl)
    },
    initialize = function(numbers,integer) {
        self$numbers <- numbers
        self$integer <- integer
    }
    )
)
test3.obj <- square3$new(list(1,2,3),2)
test3.obj$square.numbers()
test3.obj$squares

# [[1]] 
# [1] 3
#
# [[2]]
# [1] 6
#
# [[3]]
# [1] 11

1 ответ

Решение

С классами R6 каждый раз, когда вы создаете экземпляр объекта, этот объект получает копию каждой функции / метода с измененной средой. Функциям присваивается среда, в которой self указывает на публичную среду объекта (это публичное лицо объекта), и private указывает на частную среду объекта.

Это отличается от методов S3, которые не копируются для каждого экземпляра объекта.

Подводя итог: с R6 все автономно в объекте; с S3 объект не содержит методов.

Я не очень знаком с использованием parLapply, но я думаю, что можно с уверенностью полагаться на то, что parLapply,

Другие вопросы по тегам