Dear  Ivan,

thanks a lot for the detailed analysis. This is excellent  and answers
my question. Unfortunately it is difficult to find any documentation on
this topic.

I now understand this is not a formal library  auto-loading feature.

What I still see as problematic is that in this way one can get two
different results when trying to access the  same object in the same 
way,  without any error or warning message.

Thanks again!

Best regards

Hilmar

On 12.02.25 14:09, Ivan Krylov wrote:
В Tue, 11 Feb 2025 13:51:48 +0100
H B via R-help <r-help@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.


______________________________________________
R-help@r-project.org mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide https://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.

Reply via email to