convert(from, to)
is a built-in generic for converting an object from
one type to another. It is special in three ways:
It uses double-dispatch, because conversion depends on both
from
andto
.It uses non-standard dispatch because
to
is a class, not an object.It doesn't use inheritance for the
to
argument. To understand why, imagine you have written methods to objects of various types toclassParent
. If you then create a newclassChild
that inherits fromclassParent
, you can't expect the methods written forclassParent
to work because those methods will returnclassParent
objects, notclassChild
objects.
convert()
provides a default implementation when from
inherits from
to
. This default strips any properties that from
possesses that to
does not.
If you are converting an object solely for the purposes of accessing a method
on a superclass, you probably want super()
instead. See its docs for more
details.
Arguments
- from
An S7 object to convert.
- to
An S7 class specification, passed to
as_class()
.- ...
Other arguments passed to custom
convert()
methods.
Examples
foo1 <- new_class("foo1", properties = list(x = class_integer))
foo2 <- new_class("foo2", foo1, properties = list(y = class_double))
# S7 provides a default implementation for coercing an object to one of
# its parent classes:
convert(foo2(x = 1L, y = 2), to = foo1)
#> <foo1>
#> @ x: int 1
# For all other cases, you'll need to provide your own.
try(convert(foo1(x = 1L), to = class_integer))
#> Error : Can't find method for generic `convert()` with dispatch classes:
#> - from: <foo1>
#> - to : <integer>
#>
method(convert, list(foo1, class_integer)) <- function(from, to) {
from@x
}
convert(foo1(x = 1L), to = class_integer)
#> [1] 1
# Note that conversion does not respect inheritance so if we define a
# convert method for integer to foo1
method(convert, list(class_integer, foo1)) <- function(from, to) {
foo1(x = from)
}
convert(1L, to = foo1)
#> <foo1>
#> @ x: int 1
# Converting to foo2 will still error
try(convert(1L, to = foo2))
#> Error : Can't find method for generic `convert()` with dispatch classes:
#> - from: <integer>
#> - to : <foo2>
#>
# This is probably not surprising because foo2 also needs some value
# for `@y`, but it definitely makes dispatch for convert() special