Skip to content

Feature request: pass name to property setter #552

@teunbrand

Description

@teunbrand

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions