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

Running examples apparently uses print() instead of show() #2848

Open
rvlenth opened this issue Jan 30, 2025 · 5 comments · May be fixed by #2860
Open

Running examples apparently uses print() instead of show() #2848

rvlenth opened this issue Jan 30, 2025 · 5 comments · May be fixed by #2860

Comments

@rvlenth
Copy link

rvlenth commented Jan 30, 2025

My package has different print() and show() methods. When I enter an expression on the console, the results are displayed using show(), not print(). A case in point is running example code for package functions. I think we would want to see what's displayed on the console; however, evidently pkgdown renders example results using print() rather than show().

I noticed this snippet for the man page for emmeans::ref_grid() on my pkgdown site:

fiber.lm <- lm(strength ~ machine*diameter, data = fiber)
ref_grid(fiber.lm)
#>  machine diameter prediction    SE df
#>  A           24.1       40.2 0.777  9
#>  B           24.1       41.6 0.858  9
#>  C           24.1       38.5 0.966  9
#> 

The above results are what is shown using print(). However, if I enter the code on the console, I see:

> fiber.lm <- lm(strength ~ machine*diameter, data = fiber)
> ref_grid(fiber.lm)
'emmGrid' object with variables:
    machine = A, B, C
    diameter = 24.133

... which are the results of show().

I also note that the reprex package *does use show(). Here are results using reprex::reprex():

library(emmeans)
## Welcome to emmeans.
## Caution: You lose important information if you filter this package's results.
## See '? untidy'
fiber.lm <- lm(strength ~ machine*diameter, data = fiber)
ref_grid(fiber.lm)
## 'emmGrid' object with variables:
##     machine = A, B, C
##     diameter = 24.133

ref_grid(fiber.lm) |> show()
## 'emmGrid' object with variables:
##     machine = A, B, C
##     diameter = 24.133

ref_grid(fiber.lm) |> print()
##  machine diameter prediction    SE df
##  A           24.1       40.2 0.777  9
##  B           24.1       41.6 0.858  9
##  C           24.1       38.5 0.966  9

Created on 2025-01-30 with reprex v2.1.1
What we see here is the default, plus explicit pipes to show() and print().

I believe that pkgdown should use show() when it renders example output.

Note

I reference my site above, but probably by the time you review this issue, it will be rendered differently, as I changed the print method to show so as to get what I want to see on the site. However, I still think this is a bug in pkgdown and will revert to my old code when you fix it.

@jayhesselberth
Copy link
Collaborator

My understanding is that show() is more limited to displaying results from S4 objects.

I think we could try overloading pkgdown_print in cases where you are using show() for S4 objects.

pkgdown_print.default <- function(x, visible = TRUE) {
if (!visible) {
return(invisible())
}
# inlined from htmltools::is.browsable()
if (isTRUE(attr(x, "browsable_html", exact = TRUE))) {
x
} else {
print(x)
}
}

@rvlenth
Copy link
Author

rvlenth commented Feb 24, 2025

The documentation for show() states:

Objects from an S4 class (a class defined by a call to setClass) will be displayed automatically is if by a call to show. S4 objects that occur as attributes of S3 objects will also be displayed in this form; conversely, S3 objects encountered as slots in S4 objects will be printed using the S3 convention, as if by a call to print.

I believe there is a typo in this; the word after "automatically" should be "as", not "is". But it is clear that if an S4 object is created on the console, it should be displayed using the show() method. That is, show() overrides print() for S4 objects.

The context of this issue is how pkgdown renders examples. A look at the code for example indicates that the text of the example code is retrieved and then sourced. It does not invoke either a print() or a show() method. Thus, it is clear that the correct way to display example results is the way they would be displayed on the console -- using show() if it is an S4 object and print() if it is an S3 object.

The tarballs for emmeans versions 1.10.6 and earlier are available from CRAN and could be used to test if the right thing is being done. Version 1.10.7 contains a workaround to force pkgdown to render example outputs correctly. But with 12,000 R packages (I think that's about the number), surely this issue occurs with some other packages.

@rvlenth
Copy link
Author

rvlenth commented Feb 24, 2025

You had me doubting myself, but I think show() invokes print() for S3 objects. For example:

> 1:5 |> show()
[1] 1 2 3 4 5

You can see this goes through the default method:

> getMethod("show", "ANY")
Method Definition (Class "derivedDefaultMethod"):

function (object) 
showDefault(object)
<bytecode: 0x0000015a68cb0418>
<environment: namespace:methods>

Signatures:
        object
target  "ANY" 
defined "ANY" 

And a look at the code for showDefault.

So I think you fix the problem simply by replacing line 28 of pkgdown_print.R with show(x).

jayhesselberth added a commit that referenced this issue Feb 25, 2025
@jayhesselberth jayhesselberth linked a pull request Feb 25, 2025 that will close this issue
@jayhesselberth
Copy link
Collaborator

Can you install this branch and rebuild your site?

pak::pak("r-lib/pkgdown@show-examples")

@rvlenth
Copy link
Author

rvlenth commented Feb 25, 2025

@jayhesselberth OK, I have done this, and the branch seems to work correctly.

First, I reverted to the previous print.emmGrid() method so that we can observe the issue in question.

Consider the first example for ref_grid()...

The example run from the console:

> fiber.lm <- lm(strength ~ machine*diameter, data = fiber)
> ref_grid(fiber.lm)
'emmGrid' object with variables:
    machine = A, B, C
    diameter = 24.133

This should be considered the "correct" results since it is what we see on the console.

The example after building the site with pkgdown 2.1.1:

fiber.lm <- [lm](https://rdrr.io/r/stats/lm.html)(strength ~ machine*diameter, data = fiber)
ref_grid(fiber.lm)
#>  machine diameter prediction    SE df
#>  A           24.1       40.2 0.777  9
#>  B           24.1       41.6 0.858  9
#>  C           24.1       38.5 0.966  9
#>

This is incorrect.

The example after building the site with pkgdown 2.1.1.9000:

fiber.lm <- [lm](https://rdrr.io/r/stats/lm.html)(strength ~ machine*diameter, data = fiber)
ref_grid(fiber.lm)
#> 'emmGrid' object with variables:
#>     machine = A, B, C
#>     diameter = 24.133

This is correct.

I can try to send you a link to the complete sites if you need them, but this satisfies me that the issue has been addressed. Thanks.

PS -- My regular pkgdown site for emmeans at github.io has not been modified. That site is built by GitHub action. It looks correct because it is based on my modified print.emmGrid() method that works around this issue.

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

Successfully merging a pull request may close this issue.

2 participants