Last active
August 5, 2019 06:42
-
-
Save mihaiconstantin/df755017643ff08d8ad32d51db42cf59 to your computer and use it in GitHub Desktop.
Code example for StackOverflow question on `foreach` and `R6` classes (https://stackoverflow.com/questions/57349958).
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# # # Scope of the issue: | |
# | |
# - without the following line `object$parent_env <- environment()` (i.e., line 54 below), it throws an error: | |
# - `Error in { : task 1 failed - "object 'Work' not found"`. | |
# | |
# - I would like to know: | |
# 1. what are some potential pitfalls when assigning the `parent_env` inside `foreach` | |
# 2. why does it work in the first place | |
# Minimal reproducible example: | |
Work <- R6::R6Class("Work", | |
public = list( | |
values = NULL, | |
initialize = function() { | |
self$values <- "some values" | |
} | |
) | |
) | |
# Now, the following `Task` class uses the `Work` class in the constructor. | |
Task <- R6::R6Class("Task", | |
private = list( | |
..work = NULL | |
), | |
public = list( | |
initialize = function(time) { | |
private$..work <- Work$new() | |
Sys.sleep(time) | |
} | |
) | |
) | |
# In the `Factory` class, the `Task` class is created and the `foreach` is implemented in `..m.thread()`. | |
Factory<- R6::R6Class("Factory", | |
private = list( | |
..warehouse = list(), | |
..m.thread = function(object, amount, ...) { | |
cluster <- parallel::makeCluster(parallel::detectCores() - 1) | |
doParallel::registerDoParallel(cluster) | |
private$..warehouse <- foreach::foreach(1:amount, .export = ls(parent.env(self$.__enclos_env__))) %dopar% { | |
# What exactly does `environment()` encapsulate in this context? | |
object$parent_env <- environment() | |
# Instantiate the class that uses `Work` in the constructor. | |
object$new(...) | |
} | |
parallel::stopCluster(cluster) | |
} | |
), | |
public = list( | |
initialize = function(object, ..., amount = 10) { | |
private$..m.thread(object = object, amount = amount, ...) | |
} | |
) | |
) | |
# Then, it is called as: | |
library(foreach) | |
x = Factory$new(Task, time = 2, amount = 10) | |
# End of file. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment