Kyle Brandt
Kyle Brandt

Reputation: 28407

Set Methods in R without Assignment

I would like to have some post initialize replacement methods in R that can me called without an assignment operator.

So for example:

I would like to be able to call setNode(o) and replace slots in object o without having to call something like like setnode(o) <- c("foo", "bar"). The reason I want to do this is because I want there to be some interactivity in these (i.e. select.list) without the user of the method having to be aware of the details of the assignment.

Is this possible?

Upvotes: 2

Views: 606

Answers (1)

Martin Morgan
Martin Morgan

Reputation: 46866

I don't really understand your use case, but... syntax like

o <- setNode(o, c("foo", "bar"))

will, if you don't go through contortions, follow the usual copy-on-change rules of R and make a copy of o, rather than replace slot values in o. Replacement methods

node(o) <- c("foo", "bar")

update o in place. I use node rather than setNode, because the setting is implicit in the use. There is nothing that says that node<- has to do anything related to the object structure, for instance

setClass("Node", representation(n="integer", value="character"),
         prototype=prototype(n=0L))
setGeneric("node<-", function(x, ..., value) standardGeneric("node<-"))
setReplaceMethod("node", "Node", function(x, ..., value) {
    x@n <- x@n + 1L
    x@value <- toupper(value)
    x
})

and then

> o <- new("Node")
> o
An object of class "Node"
Slot "n":
[1] 0

Slot "value":
character(0)

> node(o) <- c("foo", "bar")
> o
An object of class "Node"
Slot "n":
[1] 1

Slot "value":
[1] "FOO" "BAR"

I'm not sure how this relates to your desire "I want there to be some interactivity"; you could write code that had a more call-like syntax, as

> do.call("node<-", list(x=o, value=c("foo", "bar")))
An object of class "Node"
Slot "n":
[1] 2

Slot "value":
[1] "FOO" "BAR"

but this isn't doing anything different from node(o) <- ....

Choose a reference class (these are build on top of S4, so S4-isms like setOldClass apply here) if that is appropriate for the content of the class, not for the interface provided. A data base connection, for example, might be appropriate for a reference class, because there is just a single entity on disk that you are interacting with; mostly, using reference classes will confuse your R users expecting copy-on-change semantics.

Upvotes: 2

Related Questions