How to call a function inside of a RefClass

Hello, I can't figure out how to call the sayMyNameIs function from within RCPersonAcc class

get

# Error in eval(ei, envir) : attempt to apply non-function

Was trying to follow these resources
http://charlotte-ngs.github.io/RExperimentsWithS4RC/ExperimentsWithS4AndRef.html
https://bookdown.org/rdpeng/RProgDA/object-oriented-programming.html

RCPersonAcc <- setRefClass(Class = "RCPersonAcc",
                           fields = list(
                             givenName = "character", 
                             familyName = "character",
                             emailAddress = "character",
                             yearOfBirth = "numeric"),
                           
                           methods = list(
                             initialize = function() {
                               .self$greet()
                             },
                             greet = function() {
                               cat(paste0("Hello", ".\n"))
                               # return fails for 
                               # return ("hello")
                             },
                             sayMyNameIs = function() {
                               cat(paste0("My name is ", .self$givenName, ".\n"))
                             }
                           )
)

bob <- RCPersonAcc$new()
bob <- RCPersonAcc$accessors(c("givenName", "familyName", "emailAddress", "yearOfBirth"))
bob$setGivenName("Robert")
bob$setFamilyName("Miller")
bob$setEmailAddress("bob@miller.com")
bob$setYearOfBirth(1963)

cat("Family Name:   ", bob$getFamilyName(), "\n",
    "Given Name:    ", bob$getGivenName(), "\n",
    "Email address: ", bob$getEmailAddress(), "\n",
    "Year of birth: ", bob$getYearOfBirth(), "\n")


bob$sayMyNameIs()
# Error in eval(ei, envir) : attempt to apply non-function

Anybody have any idea how to call a function from within a class excluding when it's initialized?

Hi @300_bananas ,

the link you provided Experiments With S4 Classes And With Reference Classes has the answer in the section Please note: methods after accessor

Add this (remove the function from the setRefClass call) and it will work

bob <- RCPersonAcc$methods(sayMyNameIs = function() {
  cat(paste0("My name is ", givenName, ".\n"))
}
)
bob$sayMyNameIs()

since the function will be defined after the bob <- RCPersonAcc$accessors(c("givenName", "familyName", "emailAddress", "yearOfBirth")) line and you also don't have to do the .self referencing anymore. The section mentioned above explains it very well.

Full code:

RCPersonAcc <- setRefClass(Class = "RCPersonAcc",
                           fields = list(
                             givenName = "character", 
                             familyName = "character",
                             emailAddress = "character",
                             yearOfBirth = "numeric"),
                           
                           methods = list(
                             initialize = function() {
                               .self$greet()
                             },
                             greet = function() {
                               cat(paste0("Hello", ".\n"))
                               # return fails for 
                               # return ("hello")
                             }
                           )
)

bob <- RCPersonAcc$new()
bob <- RCPersonAcc$accessors(c("givenName", "familyName", "emailAddress", "yearOfBirth"))
bob$setGivenName("Robert")
bob$setFamilyName("Miller")
bob$setEmailAddress("bob@miller.com")
bob$setYearOfBirth(1963)

cat("Family Name:   ", bob$getFamilyName(), "\n",
    "Given Name:    ", bob$getGivenName(), "\n",
    "Email address: ", bob$getEmailAddress(), "\n",
    "Year of birth: ", bob$getYearOfBirth(), "\n")

bob <- RCPersonAcc$methods(sayMyNameIs = function() {
  cat(paste0("My name is ", givenName, ".\n"))
}
)

bob$sayMyNameIs()

Thanks for the help vedoa!

I'm quite new to the R language and am pleased that I can have classes in R like I would in C++ or other OOP languages (without using say, Rcpp)

The approach you shared works even with the addition of other people

jane <- RCPersonAcc$new()
jane$setGivenName("Jane")
jane$setFamilyName("Argo")
jane$setEmailAddress("jano2@gmail.com")
jane$setYearOfBirth(2000)
jane$sayMyNameIs()

I also found another approach I could use for having classes in R that makes use of the " aoosClasses" library

https://cran.r-project.org/web/packages/aoos/vignettes/aoosClasses.html

There seems to even be "s7" library

Wonder which approach is better but at least both work

@300_bananas under Introduction | Advanced R you will find an overview about OOP in R by one of the most prolific R developers Hadley Wickham @hadley (author of ggplot2 -and most of the stuff in the tidyverse-, devtools, httr etc).

So given your background probably the R6 approach will feel by far the most natural - since it is the closest that you will come to classic OOP style of programming. Only downside - it is an extra package (has minimal dependencies).

The S7 approach is a new experimental one trying to combine the strengths of S3 and S4. Here the talk by Hadley for those who are intersetd https://www.youtube.com/watch?v=P3FxCvSueag (at the time of the recording it was still named R7 but they changed it to S7).

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.