-
Notifications
You must be signed in to change notification settings - Fork 41
Description
I've found it useful to declare properties outside a class definition and recycle the property definition for various classes or for similar properties within one class.
The issue I'm running in to is that property setters don't have access to the name of the property that is being set.
In the example below, I cannot recycle the colour property for fill
, because the setter function hardcodes the name.
library(S7)
property_colour <- new_property(
class = class_character,
setter = function(self, value) {
# Must I hardcode the property name?
prop(self, "colour") <- as.character(value)
self
}
)
rectangle <- new_class(
"rectangle",
properties = list(
colour = property_colour,
fill = property_colour
)
)
x <- rectangle("red", "blue")
#> Error: <rectangle> object properties are invalid:
#> - @fill must be <character>, not <NULL>
Created on 2025-07-23 with reprex v2.1.1
My current solution to this problem is to make a property factory like so:
library(S7)
property_colour <- function(name) {
force(name)
new_property(
class = class_character,
setter = function(self, value) {
prop(self, name) <- as.character(value)
self
}
)
}
rectangle <- new_class(
"rectangle",
properties = list(
colour = property_colour("colour"),
fill = property_colour("fill")
)
)
x <- rectangle("red", "blue")
Created on 2025-07-23 with reprex v2.1.1
But this solution is a bit unwieldy because I still have to declare the "colour"
and "fill"
names twice: once in the list names and once as argument to property_colour()
. If we could somehow automatically access the property name that is being set from the context of the setter function, this would be a much smoother experience.