简体   繁体   中英

When are accessor methods for S4 objects called in R?

Not quite sure how to ask this question without going into a great deal of detail about my specific programming problem. So, this question is slightly related, but much simpler. I'm trying to understand the procedure R applies when assigning to a slot of an S4 class. I have custom access and assignment functions, "$" and "$<-".

I note two things:

  1. the assignment will work when I'm using brackets to subset a specific slot, even though I've not provided any mechanism for doing so. I trust this is merely R's eager embrace of vectorized code. This is fine, but what if I want to enable different subsetting logic? In the toy example below, assume that I'd like to subset based on a match to birthdate.
  2. When assigning to a subsetted slot, the "$" accessor will be called. Why is this?

Following is a toy example for illustration. Comment on point 1 and an answer to point 2 are much appreciated.

setClass("Person"
     , representation(FirstName = "character"
                      , LastName = "character"
                      , Birthday = "Date")
)

setMethod("$", signature(x = "Person"), function(x, name) {
  print("Just called $ accessor")
  slot(x, name)
})

setMethod("$<-", signature(x = "Person"), function(x, name, value) {
 print("Just called $ assignment")
  slot(x, name) = value
  x
})

objPeople = new("Person"
                , FirstName=c("Ambrose", "Victor", "Jules")
                , LastName=c("Bierce", "Hugo", "Verne")
                , Birthday=seq(as.Date("2001/01/01"), as.Date("2003/12/31"), by="1 year"))

# This assignment will work. When assigning, there will be a call to the "$" accessor function. Why?
objPeople$FirstName[2] = "Joe"

# This assignment will not make a call to the "$" accessor function. Why?
objPeople$FirstName = "Ambroze"

Remember that [ is just another function, as is [<- . So in order to do

objPeople$FirstName[2] = "Joe"

The $ is going to run first and return something that the [<- can operate on. Something like

'$<-'(objPeople, "FirstName", '[<-'( '$'(objPeople, "FirstName"), 2, "Joe"))

So in order to subset, it has to extract the first name. But with

 objPeople$FirstName = "Ambroze"

That's just a

'$<-'( objPeople, "FirstName", "Ambroze")

so you don't need to call the accessor. You are just directly calling the assignment function.

If you wanted to have a custom subsetter on your class, it would be at the Person[] level. If you wanted a custom subsetter on the FirstName slot, you would have to make the FirstName slot a class of it's own where you could re-define the [ method.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM