klmr / box

Write reusable, composable and modular R code
https://klmr.me/box/
MIT License
829 stars 47 forks source link

function not exported by "app/logic/file" #356

Closed Andryas closed 4 months ago

Andryas commented 4 months ago

Error description

Sometimes, when I add a new function to a script, and I try to use box::use, it keeps giving me the error "function not exported by app/logic/file, even though the function has the header #' @export, and it's there.

For this case that I am showing, if I move the function to another file.R everything works ok, but I really would like to understand why can't I add a new function in the same script R.

Screenshot 2024-02-26 at 1 25 07 PM

Screenshot 2024-02-26 at 1 25 59 PM

R version

R version 4.3.2 (2023-10-31)
Platform: aarch64-apple-darwin23.0.0 (64-bit)
Running under: macOS Sonoma 14.3.1

Matrix products: default
BLAS:   /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib 
LAPACK: /opt/homebrew/Cellar/r/4.3.2/lib/R/lib/libRlapack.dylib;  LAPACK version 3.11.0

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

time zone: America/Toronto
tzcode source: internal

attached base packages:
[1] stats     graphics  grDevices datasets  utils     methods   base     

loaded via a namespace (and not attached):
 [1] compiler_4.3.2  magrittr_2.0.3  cli_3.6.2       tools_4.3.2     glue_1.7.0      vctrs_0.6.5     box_1.2.0       stringi_1.8.3   stringr_1.5.1   digest_0.6.34   lifecycle_1.0.4 rlang_1.1.3     renv_1.0.3      pak_0.7.1       purrr_1.0.2

‘box’ version

1.2.0

klmr commented 4 months ago

Hi,

To make it easier to reproduce the issue, it would be helpful if you could post the code and error message as text, and give a step-by-step run-down of what you did to reproduce the error.

I would guess that you developed the module iteratively. That is, you first only defined md5, and imported the module. Then, in the same R session, you imported the module again after modifying the module’s code.

If that’s the case, then the error is intentional, because ‘box’ caches modules when you first load them, and does not reload them. This is necessary for efficiency, but also for correctness (when a module is imported by multiple different places, it is usually expected to refer to the same entity, e.g. to be able to exchange state).

You can use box::reload() to force-reload a module. However, this only works on modules themselves, not on imports from modules, so it won’t work in your case. Instead, you can use box::purge_cache() to force-unload all loaded modules. Afterwards, box::use() will reload a module from the modified code. I am working on auto-reloading functionality (#234) which will be useful during development, but which will by necessity make loading of modules quite a bit slower.


As an aside, your module app/logic/utils does not actually use any if its imports: you import and attach digest and map, but you do not use them. Instead, you use digest::digest and purrr::map. This circumvents the box::use() declaration. Remove digest:: and purrr:: to use the imports instead.

Andryas commented 4 months ago

I understood. My problem happened while testing the Rhino package to develop shiny applications which use the box package. As you said, I tried to import the module after changing it, but even using box::purge_cache, I couldn't run the application. Do you have any other suggestions?

Andryas commented 4 months ago

I ran some tests, and apparently, my problem was an extra space after export, #' @export; when I changed it to #' @export, it worked.