Hi all,
I believe that 'do.call' shows inconsistent/undocumented behavior when its 'what' argument is of the format "pkg::fun". The documentation (?do.call) suggests that
what: either a function or a non-empty character string naming the function to be called.
Thus, I expected that all four of below formats of the value for the 'what' argument would work, here I use 'utils::person' as an example:
Three formats work:
do.call(person, list(given = "Jane", family = "Doe"))
do.call("person", list(given = "Jane", family = "Doe"))
do.call(utils::person, list(given = "Jane", family = "Doe"))
but the format "pkg::fun" doesn't work as I expected:
do.call("utils::person", list(given = "Jane", family = "Doe"))
Error in `utils::person`(given = "Jane", family = "Doe") :
could not find function "utils::person"
This seemingly inconsistent behavior of 'do.call' is also exposed when working in parallel and the message doesn't make it easy to see that this error derives actually from 'do.call'.
library(parallel)
cl <- makePSOCKcluster(2)
These work
clusterCall(cl, person, list(given = "Jane", family = "Doe"))
clusterCall(cl, "person", list(given = "Jane", family = "Doe"))
clusterCall(cl, utils::person, list(given = "Jane", family = "Doe"))
This doesn't work
clusterCall(cl, "utils::person", list(given = "Jane", family = "Doe"))
Error in checkForRemoteErrors(lapply(cl, recvResult)) :
2 nodes produced errors; first error: could not find function "utils::person"
This is again not obvious from the documentation (?clusterCall): fun, FUN: function or character string naming a function.
This behavior of 'clusterCall' is because the function 'makePSOCKcluster' calls newPSOCKnode() which calls .slaveRSOCK(), which calls slaveLoop(). This is then waiting and on receving an appropriate message will call 'do.call':
value <- tryCatch(do.call(msg$data$fun, msg$data$args, quote = TRUE), error = handler)
Thus, if 'msg$data$fun' (as received from recvData() which was sent via sendData(), via postNote() from function sendCall() wrapped in clusterCall()) is of the type "pkg::fun", then this will fail as above and work otherwise.
## Temporary work-around: re-define function in local namespace and export to workers
and thus expresses this same inconsistent behavior of do.call. I cannot avoid calling with pkg::fun because a package should not attach another package and change the search path of the user.
## My installation
sessionInfo()
R version 3.4.1 (2017-06-30)
Platform: x86_64-apple-darwin16.6.0 (64-bit)
Running under: macOS Sierra 10.12.5
Matrix products: default
BLAS: /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib
LAPACK: /opt/local/Library/Frameworks/R.framework/Versions/3.4/Resources/lib/libRlapack.dylib
locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
attached base packages:
[1] stats graphics grDevices utils datasets methods base
loaded via a namespace (and not attached):
[1] compiler_3.4.1
I would appreciate any help with identifying whether this is indeed inconsistent/undocumented behavior of 'do.call' or whether I am simply missing the point and how to deal with the situation.
Thank you,
Daniel Schlaepfer