The equivalent of 'this' or 'self' in R
Asked Answered
C

1

7

I am looking for the equivalent of python's 'self' keyword or java's 'this' keyword in R. In the following example I am making an S4 object from a method of a different S4 object and need to pass a pointer to myself. Is there something in the language to help me do this?

MyPrinter <- setRefClass("MyPrinter",
  fields = list(obj= "MyObject"),
  methods = list(
    prettyPrint = function() {
      print(obj$age)
      # do more stuff
    }
  )
)

MyObject <- setRefClass("MyObject",
  fields = list(name = "character", age = "numeric"),
  methods = list(
    getPrinter = function() {
      MyPrinter$new(obj=WHAT_GOES_HERE) #<--- THIS LINE
    }
  )
)

I can do this with a freestanding method but I was hoping for a nice object-oriented way of doing this operation in R. Thanks

Contemplation answered 19/7, 2016 at 0:49 Comment(1)
This is a 'reference class' (?ReferenceClasses or ?setRefClass) rather than S4 class per se (?Classes, ?Methods). From ?ReferenceClasses, see .self.Sweetheart
S
8

Reference class (RC) objects are basically S4 objects that wrap an environment. The environment holds the fields of the RC object, and is set as the enclosing environment of its methods; that's how unqualified references to the field identifiers bind to the instance's fields. I was able to find a .self object sitting in the environment that I believe is exactly what you're looking for.

x <- MyObject$new(); ## make a new RC object from the generator
x; ## how the RC object prints itself
## Reference class object of class "MyObject"
## Field "name":
## character(0)
## Field "age":
## numeric(0)
is(x,'refClass'); ## it's an RC object
## [1] TRUE
isS4(x); ## it's also an S4 object; the RC OOP system is built on top of S4
## [1] TRUE
slotNames(x); ## only one S4 slot
## [1] ".xData"
[email protected]; ## it's an environment
## <environment: 0x602c0e3b0>
environment(x$getPrinter); ## the RC object environment is set as the closure of its methods
## <environment: 0x602c0e3b0>
ls([email protected],all.names=T); ## list its names; require all.names=T to get dot-prefixed names
## [1] ".->age"       ".->name"      ".refClassDef" ".self"        "age"          "field"
## [7] "getClass"     "name"         "show"
[email protected]$.self; ## .self pseudo-field points back to the self object
## Reference class object of class "MyObject"
## Field "name":
## character(0)
## Field "age":
## numeric(0)

So the solution is:

MyObject <- setRefClass("MyObject",
    fields = list(name = "character", age = "numeric"),
    methods = list(
        getPrinter = function() {
            MyPrinter$new(obj=.self)
        }
    )
)
Satisfactory answered 19/7, 2016 at 1:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.