Closed vdanglse closed 1 year ago
I'm afraid this is one of the hard things ("cache invalidation and naming things"). More specifically, this is a classic recursive caching issue.
The problem is that import
checks any module script referenced in import::from()
for file modification time (see here). But in your case, because module.R
has not changed, that code is never run, so submodule.R
is never checked for modification time.
I believe that solving this in an automatic way would require full awareness of any recursive calls inside a module and would quickly evolve into a full pipeline tool (such as the https://github.com/ropensci/targets/ package). So unfortunately, I don't expect that it will make its way into the package.
Thank you for clarifying. In this case, is there an easy way to override the caching and force import::from
to run as if we restarted the R session?
Well, out of curiosity, I did check out ways to do this doing this. First it is important to note that recursive imports are only supported when the inner import uses import::here()
(as your example does). This is because the inner modules functions end up in strange places (in terms of R environments).
For the case where the outer module does that (use import::here()
to import the inner module), but then you use import::from()
to import the outer module, the following code should work.
> import::from(module_recursive_outer_here.R, print_title_text)
> print_title_text("hi friend, how are you")
[1] "Hi Friend, How are you"
> # Change the inner function to_title()
> rm(list=ls("imports"), pos="imports")
> unloadNamespace("import")
> import::from(module_recursive_outer_here.R, print_title_text)
> print_title_text("hi friend, how are you")
[1] "HI FRIEND, HOW ARE YOU"
This uses some modules already in the test code.
What it does is delete all the visible objects from the imports
environment to force reloading the outer package, and then unloads the import
namespace (note the difference in the ending), so that it doesn't find the names of the inner function when it goes looking.
Note, this is definitely not part of the specified behavior or the "package contract". It will probably not break any time soon, but don't rely on it in production code (should be OK though, because this is inherently a workaround to simplify development, not final code).
Hope it helps!
Thank you, that is very helpful.
The v.1.3.1
release is now out, and I'm doing a bit of a cleanup in the issues.
Since using import
to update utility modules dynamically within a living R session is not within the scope of import, solving the recursive issue is hard, and it seems there is an acceptable workaround, I'm closing this issue now. If other matters related to this arise, or if someone is able to contribute a feature to implement this well, feel free to reopen.
First of all, thank you for the amazing package. I have greatly enjoyed using it. However, I have an issue with nesting
import
statements which I can't quite solve.I have the following folder structure:
File 1: main.R
File 2: module.R
File 3: submodule.R
The first time I run
main.R
, it returns1
as expected. However, if I change the definition ofg
insubmodule.R
tog <- \(){2}
and rerunmain.R
, the result is still1
. I figured thatimport::from
would checkmodule.R
to see if it has been changed before reimportingf
. If I make some superficial change tomodule.R
(e.g. adding extra linebreaks) before runningmain.R
, it would return the correct result.Would there be an easy way to overcome this, and is there something that I'm missing here?