Home > OS >  setMethod distinguish between using to "assign" to variable and pure "info" call
setMethod distinguish between using to "assign" to variable and pure "info" call

Time:07-09

Anyone know if the following can be achieved in R specifically S4

foo <- setClass("foo", contains = "matrix")
foo <- function(m = matrix(1:9, nrow = 3)) new("foo", m)

setMethod("dim", signature = "foo", 
  function(x) {
       dd <- dim([email protected])
       cat("foo dims: ")
       return(dd)
}
)

# followed by  
bar <- foo()

How or can it be achieved to distinguish between ...

dim(bar)
# which gives
foo dims: [1] 3 3 
# and calling dim to assign the return value to a variable 
# ie this call
bardims <- dim(bar)
# which does 
foo dims: 
# but I don't want it to produce any cat output to the console/screen

in the second case I would like to suppress the cat(....) part of the original "dim,foo-method". I would not mind defining something like setMethod('<-dim', 'foo', function(.... but I guess that is not available? Info: I am using R-4.0.5 here

CodePudding user response:

It's generally not a great idea to use cat() to spit out messages in function. It gives users very little control over how they display and makes it very difficult to grab those values should they ever want them.

A possible alternative is to annotate the response with a custom class that will output a message only when print()-ed. Hence it will not show up during assignment because those results are returned invisibly.

Here's an S3 class that can help

annotate_value <- function(val, msg) {
  attr(val, "message") <- msg
  class(val) <- c("annotated", class(val))
  val
}
print.annotated <- function(x) {
  class(x) <- setdiff(class(x), "annotated")
  cat(attr(x, "message"))
  attr(x, "message") <- NULL
  print(x)
}

And then you use it like


setMethod("dim", signature = "foo", 
          function(x) {
            dd <- dim([email protected])
            annotate_value(dd, "foo dims:")
          }
)

Then when you run your code, you get the desired output

bar <- foo()
dim(bar)
# foo dims:[1] 3 3
bardims <- dim(bar)
#
  •  Tags:  
  • r s4
  • Related