Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

class(S7_object) is behaving oddly since S7 v0.2.0 #491

Closed
jeffkimbrel opened this issue Nov 9, 2024 · 3 comments
Closed

class(S7_object) is behaving oddly since S7 v0.2.0 #491

jeffkimbrel opened this issue Nov 9, 2024 · 3 comments

Comments

@jeffkimbrel
Copy link

jeffkimbrel commented Nov 9, 2024

Sorry for the title - it can be edited once I know the terms for the problem I am experiencing.

I have an S7 object (called qsip_source_data) that is defined as part of an R package called qSIP2. Instances of this object that I have created and saved as .rds before S7 v0.2.0 give what I consider the correct output when running class() on them. New object, however, have the object name prepended with qSIP2:: when running class(), which is changing behavior.

> class(previously_created)
[1] "qsip_source_data" "S7_object" 
> class(newly_created)
[1] "qSIP2::qsip_source_data" "S7_object" 

This is making various aspects of my package break because I check for whether an object is the correct type with a statement like...

stopifnot("X should be of class <qsip_source_data>" = "qsip_source_data" %in% class(X))

... and this is stopping everytime on new objects with the full qSIP2::qsip_source_data as one of the classes. I can't seem to make a reproducible example because this seems specific to an S7 object defined in a package, which I assume is where the qSIP2:: is coming from.

So, I guess two questions come to mind...

  1. Did something change in the new S7 0.2.0 that would give this behavior?
  2. Should I being doing something other than "qsip_source_data" %in% class(X) to verify an object is of the right class that won't break here?

Additionally, and this might be its own issue, but methods are also not working correctly anymore and I get errors that methods don't exist for <qsip_source_data>. But, I can't seem to define them for <qSIP2::qsip_source_data> as I get an error.

Thanks for your help.

@hadley
Copy link
Member

hadley commented Nov 9, 2024

Yes, this was documented before, but it's now done automatically: when you have an S7 class in a package, you should use the package argument to automatically namespace the class. (This ensures that if some other package also defines a qsip_source_data class, you won't have conflicts).

To determine if an object inherits from a specific S7 class you can use either inherits(x, class) (in R 4.3 and later) or S7_inherits(x, class) (for all versions of R).

How are you defining methods?

@jeffkimbrel
Copy link
Author

jeffkimbrel commented Nov 9, 2024

Thanks so much for your help. I'm a biologist that knows just enough to be dangerous to myself, and obnoxious to you.

I've gone through my code changing the previous "qsip_source_data" %in% class(X) calls to inherits(source_data, c("qsip_source_data", "qSIP2::qsip_source_data")), which seems to fix that problem.

I did have saved objects in data or tests/testthat/fixtures that seemed incompatible, so I re-created both the data in data-raw and the test fixtures, and the updated objects seem to work correctly. Now, check() and test() report no issues (well, related to this at least).

I had to make the inherits() call match to both c("qsip_source_data", "qSIP2::qsip_source_data") to work in all cases. But, this may be because I had those "legacy" versions and now that I have updated those perhaps the fullqSIP2::qsip_source_data in inherits() isn't need anymore.

The generics/methods I have created now also work correctly, so I think the problems are all solved.

For full documentation here, the changes made were:

  1. added package = "qSIP2" argument to my S7::new_class calls
  2. used inherits() instead of . %in% class(X) (which was definitely hacky)
  3. recreated all test fixtures and package data objects so they were built with the current object structure

Thanks so much, I'll close for now. Still wrapping my head around OOP in R, but getting the hang of it.

@hadley
Copy link
Member

hadley commented Nov 9, 2024

FWIW you should supply the class object to inherits, not just the string representing the class name, i.e. inherits(x, qsip_source_data).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants