Object-Oriented Programming in R: The Setter Methods

[This article was first published on John Myles White: Die Sudelbücher » Statistics, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

With a little guidance from the indefatigable Hadley Wickham, I figured out today how to implement the setter methods that were missing from my example user class. To review, let’s rebuild the getter methods for my user object:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
user <- list(id = 1,
             password = '286755fad04869ca523320acce0dc6a4',
             email = '[email protected]')
 
class(user) <- 'user'
 
id <- function(x)
{
  UseMethod('id', x)
}
 
id.user <- function(user)
{
  return(user[['id']])
}
 
password <- function(x)
{
  UseMethod('password', x)
}
 
password.user <- function(user)
{
  return(user[['password']])
}
 
email <- function(x)
{
  UseMethod('email', x)
}
 
email.user <- function(user)
{
  return(user[['email']])
}

With these working, my goal was to write setter methods that would work like the ideal code below:

1
2
3
4
5
6
id(user) <- 2
 
if (id(user) == 2)
{
  print("Succeeded in editing the user's id attribute.")
}

Defining this sort of setter method turned out to require a little effort. I wasted quite a lot of time walking down dead ends, but, thankfully, Hadley gave me the exact piece of information I was missing early this morning. The dead ends were interesting in themselves, though, so I’ll review them in another post tomorrow.

For now I’ll just explain the correct implementation for my desired setter methods, which you can see below:

1
2
3
4
5
6
7
8
9
10
'id<-' <- function(x, value)
{
  UseMethod('id<-', x)
}
 
'id<-.user' <- function(x, value)
{
  x[['id']] <- value
  return(x)
}

There are three important ideas here:

  1. The generic setter method for id should be called 'id<-', which must always be quoted to prevent parsing errors.
  2. The class level setter method should be called 'id<-.user', which isn't surprising, though I had imagined it might be called 'id.user<-' at one point.
  3. The setter method should make a change to a copy of the original object and return the edited copy to the caller. R handles the assignment of this edited return value to the original object behind the scenes. In fact, not using this return value approach will make otherwise plausible looking code fail to edit your object correctly. I stumbled on that for quite a while before I was shown the light.

With this in mind, a final user class looks like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
user <- list(id = 1,
             password = '286755fad04869ca523320acce0dc6a4',
             email = '[email protected]')
 
class(user) <- 'user'
 
id <- function(x)
{
  UseMethod('id', x)
}
 
id.user <- function(user)
{
  return(user[['id']])
}
 
password <- function(x)
{
  UseMethod('password', x)
}
 
password.user <- function(user)
{
  return(user[['password']])
}
 
email <- function(x)
{
  UseMethod('email', x)
}
 
email.user <- function(user)
{
  return(user[['email']])
}
 
'id<-' <- function(x, value)
{
  UseMethod('id<-', x)
}
 
'id<-.user' <- function(x, value)
{
  x[['id']] <- value
  return(x)
}
 
'password<-' <- function(x, value)
{
  UseMethod('password<-', x)
}
 
'password<-.user' <- function(x, value)
{
  x[['password']] <- value
  return(x)
}
 
'email<-' <- function(x, value)
{
  UseMethod('email<-', x)
}
 
'email<-.user' <- function(x, value)
{
  x[['email']] <- value
  return(x)
}

To leave a comment for the author, please follow the link and comment on their blog: John Myles White: Die Sudelbücher » Statistics.

R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

Never miss an update!
Subscribe to R-bloggers to receive
e-mails with the latest R posts.
(You will not see this message again.)

Click here to close (This popup will not appear again)