r-lib / R6

Encapsulated object-oriented programming for R
https://R6.r-lib.org
Other
407 stars 56 forks source link

Override format() for R6 and R6ClassGenerator #74

Closed krlmlr closed 8 years ago

krlmlr commented 8 years ago

Fixes #73.

wch commented 8 years ago

Looks pretty good. Can you explain how it's different in the "Format" section of roxygen2 docs?

krlmlr commented 8 years ago

For data objects x, roxygen2 generates the "Format" section from the output of format(x) if @format is missing

wch commented 8 years ago

Could you bump the version to 2.1.1.9000, and also add an entry to NEWS, under a new section, 2.1.1.9xxx? Also, it would be good to note that if existing code has a format method, it will be called when the object is printed, since this could potentially cause problems.

krlmlr commented 8 years ago

Done. I think existing code is safe:

> cl <- R6Class("cl", public = list(print = function() print("print"), format = function() "format"))
> print(cl$new())
[1] "print"
> format(cl$new())
[1] "format"
wch commented 8 years ago

But what if there's a format method and no print method? I'm just thinking of a case where someone used the name format for a method that does something else entirely.

krlmlr commented 8 years ago

Still looks safe to me:

> cl <- R6Class("cl", private = list(format = function() "format"))
> format(cl$new())
[1] "<cl>\n  Public:\n    clone: function\n  Private:\n    format: function"
> print(cl$new())
<cl>
  Public:
    clone: function
  Private:
    format: function

The dispatch is at the S3 level, there's no default R6 method print() that gets invoked and forwards to format().

wch commented 8 years ago

Ah, OK. Thanks!

krlmlr commented 8 years ago

Of course you're right -- my example was wrong, using private instead of public methods: Even if dispatch is at the S3 level, a format() method will be called if it exists. I'll update the NEWS. (Technically, it's an interface change -- do you want me to bump to 3.0.0.9000?)

On that note: Perhaps the output for functions could contain the interface:

<cl>
> cl <- R6Class("cl", public = list(some_func = function(a, b = "default", ...) NULL))
> cl
<cl> object generator
  Public:
    some_func: function(a, b = "default", ...)
    clone: function()
  Parent env: <environment: R_GlobalEnv>
  Locked objects: TRUE
  Locked class: FALSE
  Portable: TRUE
wch commented 8 years ago

Glad to hear I was right. :)

Both the NEWS update and more detailed function output would be good.