[R] Unexpected result after auto-attaching of the Matrix package

Ivan Krylov |kry|ov @end|ng |rom d|@root@org
Wed Feb 12 14:09:35 CET 2025


В Tue, 11 Feb 2025 13:51:48 +0100
H B via R-help <r-help using r-project.org> пишет:

>  > class(d)  
> [1] "dgCMatrix"
> attr(,"package")
> [1] "Matrix"
>  > dim(d)  
> Loading required package: Matrix
> NULL

Here's what happens here:

1. .Primitive("dim") considers dispatching a dim() method:
https://github.com/r-devel/r-svn/blob/fa73948a1977da05788499807469e69d5a21bd98/src/main/attrib.c#L1181
2. DispatchOrEval() first considers S4 dispatch:
https://github.com/r-devel/r-svn/blob/fa73948a1977da05788499807469e69d5a21bd98/src/main/eval.c#L4152
3. But then R_has_methods(dim) finds out that no S4 methods are
currently registered for dim() - Matrix not being loaded yet - and S4
dispatch is abandoned:
https://github.com/r-devel/r-svn/blob/fa73948a1977da05788499807469e69d5a21bd98/src/main/objects.c#L1578
4. Instead, R tries usemethod(...) for S3 dispatch:
https://github.com/r-devel/r-svn/blob/fa73948a1977da05788499807469e69d5a21bd98/src/main/eval.c#L4215
5. UseMethod() wants to find out the S3 class vector for 'd' and calls
R_data_class2():
https://github.com/r-devel/r-svn/blob/fa73948a1977da05788499807469e69d5a21bd98/src/main/objects.c#L493
6. R_data_class2() sees it's an S4 object and calls
methods:::.extendsForS3(class(d)), which finally loads Matrix in order
to find out classes extended by "dgCMatrix":
https://github.com/r-devel/r-svn/blob/fa73948a1977da05788499807469e69d5a21bd98/src/main/attrib.c#L840
https://github.com/r-devel/r-svn/blob/fa73948a1977da05788499807469e69d5a21bd98/src/main/attrib.c#L736-L741
7. S3 dispatch fails for all those S4 classes or the "default" method,
so dim(d) returns attr(d, "dim") (which is not set):
https://github.com/r-devel/r-svn/blob/fa73948a1977da05788499807469e69d5a21bd98/src/main/attrib.c#L1184

Then why does print(d) work without loading Matrix first?
print.default() internally performs S4 dispatch after Matrix was loaded
by R_data_class2() on step (6) above.

So while Matrix is not being loaded by accident in your example, things
are not set up to load the packages containing S4 classes
automatically. It could become a feature request for DispatchOrEval()
to ensure that the the package owning the S4 class is loaded before
trying to dispatch an S4 method, although it could be challenging to
implement while avoiding additional slowdowns.

-- 
Best regards,
Ivan



More information about the R-help mailing list