-1

I have defined three different S4 classes in their own scripts in my R package. One of those classes uses the other two classes.

I see that devtools::load_all() loads the scripts in alphabetical order, so that if a script depends on another that is later in alphabetical order, there may be problems. Observe:

Example script a.r:

setClass("a", slots = c(name = "character"))

Example script b.r

setClass("b", slots = c(name = "character", a = "a", c = "c"))

Example script c.r:

setClass("c", slots = c(name = "character"))

When I run devtools::load_all(), the following warning appears:

Warning messages:
1: undefined slot classes in definition of "b": c(class "c") 

I do not want to rename my scripts simply to put them in alphabetical order based on when I want them to be loaded.

I do not want to define those classes in a single script, because I want to keep the code more modular.

How do I ensure that the script defining the dependent class has access to the other classes:

  1. Regardless of the names of the scripts those classes are in?
  2. Without resorting to source() since this would import other functions, objects, variables, from that script that are not needed.

In python, this is relatively trivial. One uses a syntax like:

from <relative path to .py file that defines those objects> import <desired objects>

In R, I am spinning in circles trying to accomplish something similar.

Jayden.Cameron
  • 499
  • 4
  • 17
  • 2
    It is only a warning. Unless your scripts instantiate the classes, you can create them even if they have references to unloaded classes. – Ric Feb 19 '23 at 16:54

2 Answers2

0

I found a suitable solution by digging into the Collate field in the DESCRIPTION file.

When I append this to the DESCRIPTION file, then the warning goes away when I run devtools::load_all() because files will be loaded in the order I specified rather than alphabetical order:

Collate:
    a.r
    c.r
    b.r

This does not answer the more general question about how to replicate the behavior of python by only importing specific objects defined in another script... The load_all() functionality still seems to load everything in the scripts, and the Collate section simply specifies the order... But I'll still count this as a win.

Jayden.Cameron
  • 499
  • 4
  • 17
-1

Seeing as your b.r macro would like to have class(c) defined, I strongly recommend you explicitly include the command load(c.r) at the top of the b.r macro. Otherwise when someone tries to set up something with load(b.r) rather than "load.all()` there'll be a failure anyway. Always avoid depending on the user executing something "extra" .

Carl Witthoft
  • 20,573
  • 9
  • 43
  • 73
  • Isn't `load()` meant for loading RData files first saved with `save()`? Adding `load(c.r)` to the top of `b.r` leads to a different error when then trying `load_all()`: `object c.r not found`. If you meant to suggest I should add `source("R/c.r")` to the top of `b.r`, then that is something I am explicitly trying to avoid since I only want to import the definition of the class defined in `c.r`, not everything else that may be defined in that script. – Jayden.Cameron Feb 20 '23 at 22:22
  • @Jayden.Cameron ok, yes, so use `source()` . But if you're going to be that specific with imports, then create a `thing.r` script for each class you want to define and have your `c.r` script invoke the class defintion script – Carl Witthoft Feb 21 '23 at 00:29