r-lib / R6

Encapsulated object-oriented programming for R
https://R6.r-lib.org
Other
412 stars 57 forks source link

Solution for class "SomeR6" is not exported by 'namespace:SomePackage' #261

Open gwd666 opened 2 years ago

gwd666 commented 2 years ago

I was hoping that someone could provide some hints on how to solve this issue presented/asked about a year ago on SO - since I cannot find an answer there and I am having the exact same problem with almost the same reprex (posted at another repo from my side https://github.com/tidylab/R6P/issues/19#issue-1263859008, do not get irritated by (or too focused on the detail) that it uses R6P Singleton there - one can comment out the inherit line and result will stay the same) or you can also refer to the original SO reprex for docu.

> sessionInfo()
R version 4.0.5 (2021-03-31)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 19042)

Matrix products: default

locale:
[1] LC_COLLATE=English_United States.1252
[2] LC_CTYPE=English_United States.1252   
[3] LC_MONETARY=English_United States.1252
[4] LC_NUMERIC=C
[5] LC_TIME=English_United States.1252    

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

other attached packages:
[1] SingletonTest_0.0.0.9001

loaded via a namespace (and not attached):
 [1] magrittr_2.0.3    usethis_2.1.5     devtools_2.4.3    pkgload_1.2.4    
 [5] R6_2.5.1          rlang_1.0.2       fastmap_1.1.0     tools_4.0.5
 [9] pkgbuild_1.3.1    sessioninfo_1.2.2 R6P_0.2.2         cli_3.3.0        
[13] withr_2.5.0       ellipsis_0.3.2    remotes_2.4.2     rprojroot_2.0.3  
[17] lifecycle_1.0.1   crayon_1.5.1      brio_1.1.3        processx_3.5.3   
[21] purrr_0.3.4       callr_3.7.0       fs_1.5.2          ps_1.7.0
[25] curl_4.3.2        testthat_3.1.4    memoise_2.0.1     glue_1.6.2       
[29] cachem_1.0.6      compiler_4.0.5    desc_1.4.1        prettyunits_1.1.1
[33] jsonlite_1.8.0
gwd666 commented 2 years ago

tbh it almost looks like portable = TRUE has no effect on usability of an R6 class defined in one package when trying to use it in another, despite the NAMESPACE file looking correct? Since the below code, taking S4 totally out of the equation, produces the same output:

#' @export
aNewR6 <- R6::R6Class(
    inherit = SingletonTest::Counter, 
    public = list( 
        #' @field SomeField
        #' some number
        SomeField  = 10) 
    )

giving

... 
Error: class "Counter" is not exported by 'namespace:SingletonTest'
Execution halted
.... 

despite the SingletonTest package NAMESPACE file looking like (as mentioned this has the R6P Singleton parts already dropped out):

# Generated by roxygen2: do not edit by hand

export(Counter)
importFrom(R6,R6Class)
wch commented 2 years ago

Trying to combine R6 and S4... I don't know how that would work.

R has built-in support for S4 classes. That's probably where the class "Counter" is not exported by 'namespace:SingletonTest' message is coming from. On the other hand, R does not have built-in knowledge of R6; that's entirely provided by this package.

The portable=TRUE option does matter for inheritance across packages. That's when an R6 class inherits from another R6 class in another package. It looks like you're trying to combine it with S4 somehow, and again, I don't know how that would work.

wch commented 2 years ago

One more thing I noticed in the SO issue: there are exportClass directives in the example. Try taking those out. Those are related to S4.

gwd666 commented 2 years ago

I took the S4 out of the equation all together - still the same error; or are you saying that I did something wrong with inherit = SingletonTest::Counter?

wch commented 2 years ago

I think the problem is caused by the S4-related stuff, like exportClass and importClassesFrom. Try removing all of that.

The parent package's NAMESPACE file should have export(Counter) and the child package's NAMESPACE file should have importFrom(SingletonTest, Counter).

If you can provide a minimal reprex in a github repo, that would help to diagnose the problem.

gwd666 commented 2 years ago

btw thanx for your reply and comments Give me a couple of minutes for the full "reprex" code (w/o any S4) ... for my problem I will also get rid of those "importClassesFrom" etc ... as you suggested

gwd666 commented 2 years ago

Ok - stripping it down to the "bare bones" (seems that importClassesFrom was breaking the R6 "native" inheritance) fixed it for me regarding R6 inheritance; still I was hoping that I would be able to assign an R6 object to an S4 slot sort of like an "environment"? Any idea if that can be accomplished?

gwd666 commented 2 years ago

@wch I found a way based on your input and an SO question/discussion I tried to summarize it in my "original" issue here #https://github.com/tidylab/R6P/issues/19#issuecomment-1152085454 If it's ok I am dropping that info in here for you as well in case someone else feels the need to do something similar (in the future).
And potentially you may be interested to find out why I was not able to make that importFrom fly and had to go full require on this one? Guess I can (have not checked yet) also elevate that package from Imports: up into the Depends: section of the DESCRIPTION file, should have the same effect as a require imo. I may (later) have a look at your explanations regarding 'portability' here to see if that may solve this final problem of mine.
Thanks for your replies and input. PS: R6 is great (imho)