convert {S7} | R Documentation |
Convert an object from one type to another
Description
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 two default implementations:
When
from
inherits fromto
, it strips any properties thatfrom
possesses thatto
does not (downcasting).When
to
is a subclass offrom
's class, it creates a new object of classto
, copying over existing properties fromfrom
and initializing new properties ofto
(upcasting).
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.
S3 & S4
convert()
plays a similar role to the convention of defining as.foo()
functions/generics in S3, and to as()
/setAs()
in S4.
Usage
convert(from, to, ...)
Arguments
from |
An S7 object to convert. |
to |
An S7 class specification, passed to |
... |
Other arguments passed to custom |
Value
Either from
coerced to class to
, or an error if the coercion
is not possible.
Examples
Foo1 <- new_class("Foo1", properties = list(x = class_integer))
Foo2 <- new_class("Foo2", Foo1, properties = list(y = class_double))
# Downcasting: S7 provides a default implementation for coercing an object
# to one of its parent classes:
convert(Foo2(x = 1L, y = 2), to = Foo1)
# Upcasting: S7 also provides a default implementation for coercing an object
# to one of its child classes:
convert(Foo1(x = 1L), to = Foo2)
convert(Foo1(x = 1L), to = Foo2, y = 2.5) # Set new property
convert(Foo1(x = 1L), to = Foo2, x = 2L, y = 2.5) # Override existing and set new
# For all other cases, you'll need to provide your own.
try(convert(Foo1(x = 1L), to = class_integer))
method(convert, list(Foo1, class_integer)) <- function(from, to) {
from@x
}
convert(Foo1(x = 1L), to = class_integer)
# 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)
# Converting to Foo2 will still error
try(convert(1L, to = Foo2))
# This is probably not surprising because foo2 also needs some value
# for `@y`, but it definitely makes dispatch for convert() special