klmr / box

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

Add support for using ‘box’ inside .Rprofile #313

Closed klmr closed 1 year ago

klmr commented 1 year ago

Please describe your feature request

.Rprofile is loaded via sys.source. Extend the path_test_hooks to add handling for sys.source by inspecting the call stack, finding the nearest sys.source call frame (if any) and extracting the file value from it.

This check probably needs to have medium priority because it needs to happen before checks for RStudio etc.

Unfortunately this might cause substantial slowdowns for every box::use and box::file call. On the flip side the current check is already quite slow and should be optimised further, if possible.

klmr commented 1 year ago

Correction:

.Rprofile is loaded via sys.source.

Not true. 😢 In reality it’s loaded via R_LoadProfile in the C code in main/main.c. In turn, this dispatches to R_ReplFile. Furthermore, that function gets a FILE* and doesn’t actually know the filename. Inside the context of the .Rprofile evaluation there is no stack trace, no marker from where the expressions being evaluated are read, and no other indication (as far as I can see) that we are currently inside an R profile file.

I’m currently stumped how to support this without changes to the actual R source code.

Furthermore, the same function R_LoadProfile is used to load the site file, the system profile and a Tcl/Tk frontend source file, although I think we could ignore this.


In addition, sometimes the .Rprofile file will be sourced via source or sys.source and we need to catch those cases because this will happen in cases where the user dispatches to a different .Rprofile file from a local one (e.g. ‘callr’ does this). So, really, we should just generically handle source and sys.source, but this doesn’t happen with the original .Rprofile, as it were.

klmr commented 1 year ago

… furthermore, .First is executed afterwards, in a slightly different context, but should probably be treated by ‘box’ as if it was executed inside the profile file which defined it; and unfortunately we don’t know which one that was. Unless keep.source was active, we have simply no way of finding out which.

klmr commented 1 year ago

Conclusion: currently impossible to implement in R. 😞