Closed jonthegeek closed 10 months ago
I'd just make a wrapper function:
library(S7)
prop_integer_coerce <- function(name) {
new_property(
name = name,
class = class_integer,
setter = function(self, value) {
if (rlang::is_integerish(value)) {
value <- as.integer(value)
}
prop(self, name) <- value
self
}
)
}
my_class_strict <- new_class(
"my_class_strict",
properties = list(
name = class_character,
age = prop_integer_coerce("age")
)
)
my_class_strict(name = "Jon", age = 48)
The fact that you need to specific age twice in the property list is a bug; I've filed it at #371.
As far as I can tell, it isn't possible to make a reusable
setter
in a property without wrapping new_property() in a factory, since we need to set self@property, and we don't know property's name in context.Would it be possible to either allow setter() to have more arguments, or to make the name of property (and, ideally, the caller env) available somehow?
This is how I'm currently dealing with this sort of thing (specifically something like the
_better
level). This example is somewhat contrived, but I have more-realistic cases where I want to coerce when possible (eg, values that are likely to come in as character but that I'd like to coerce to integer when that can be done so cleanly).Created on 2023-09-28 with reprex v2.0.2
Alternatively, is there a way to implement this with
class_integerish
rather thanprop_integerish
? I got close, but I had to giveclass_integerish
a named property that made printing ugly, and I still had to docaller_env(N)
tricks to make the error messages work right.