richfitz / remake

Make-like declarative workflows in R
Other
340 stars 32 forks source link

R6 Class definition fails #147

Closed sakrejda closed 7 years ago

sakrejda commented 7 years ago

I tried to have remake include another yml file that has sources defining an R6 class. R6 is included in the packages section but I get an error that R6Class is not found.

To reproduce just clone the repo: https://github.com/sakrejda/remake-fail.git Then run remake::make() from the remake-fail directory, you will get something like:

SPH-KSakrejda:whut krzysztof$ Rscript -e 'remake::make()'
[  LOAD ] 
[  READ ]            |  # loading sources
Error: while sourcing 'scripts/data-processing/time-schemes.R':
could not find function "R6Class"
Execution halted

I'm pretty sure I'm just not understanding some of the restrictions on remake but it's not clear to me why this is happening.

sakrejda commented 7 years ago

Well, fixed by replacing R6Class with R6::R6Class to work around the issue, I guess libraries are loaded after source files are processed.

richfitz commented 7 years ago

Thanks for the report - I think that this is the same issue as the (very vague) #69

At present, remake needs to read the source files in order to check dependencies and it does that before loading packages because some can be very slow (one of the motivating use-cases had a set of packages that took over 20s to load because of some heavy use of S4). What is not clear to me is why it needs to source them before packages are loaded though

This is practically an issue for only a handful of things - packages that are used at the top-level rather than within functions so it affects things like %>% (for functional sequences) and R6 because they're used slightly differently

It is very likely that the dependency detection will do badly for R6 class methods, as it already does badly on closure-based functions. If you have a public example at some point I would be interested to see how you're using R6 in this context

sakrejda commented 7 years ago

Thanks for the detailed response, that makes sense. I've been looking at a variety of build systems lately looking for one that's right for reproducible research and this type of issue bites everybody. Functional dependencies are really easy to scan for and everything else is kind of a mess. For remake it might be nice to have a way to just source some setup code at each run regardless of what the dependencies say. In this case the code is just missing a library(R6) call in the right place. When you run is via that command that generates a script it doesn't need the R6::. For this particular problem prefixing R6:: is a fine solution (maybe should be documented) so I'm closing this issue.