## 7.1 Introduction

Until now we have standard methods like `print()`, `summary()`, and `plot()`. However, we can add more common (and not so common) methods such as:

• replacement: `"[<-.toss"`
• extraction: `"[.toss"`
• testing: `is.toss()`
• addition: `"+.toss"`

## 7.2 Replacement Method

Replacement functions are those calls like `x[1] <- 3`. The function behind this expression is the replacement `"[<-"()` function. We can also create a replacement function for a given class using the notation `"[<-.class"`, where `class` is the name of the class:

``````"[<-.toss" <- function(x, i, value) {
if (value != x\$coin\$sides[1] & value != x\$coin\$sides[2]) {
stop(sprintf('\nreplacing value must be %s or %s',
x\$coin\$sides[1], x\$coin\$sides[2]))
}
x\$tosses[i] <- value
make_toss(x\$coin, x\$tosses)
}``````

Test it:

``````set.seed(3752)
dime1 <- coin(c("roosevelt", "torch"), prob = c(0.48, 0.52))
b <- toss(dime1, times = 5)
b\$tosses
#> [1] "roosevelt" "roosevelt" "roosevelt" "torch"     "torch"

# replacement
b[1] <- "torch"
b\$tosses
#> [1] "torch"     "roosevelt" "roosevelt" "torch"     "torch"``````

What about replacing out of the original range?

``````# replacement in sixth position (weird!)
b[6] <- "torch"
b
#> object "toss"
#> sides: "roosevelt", "torch"
#> prob: "0.48", "0.52"
#> total tosses: 6
#> num of roosevelt: 2
#> num of torch: 4``````

Or something like this?

``````# replacement
b[10] <- "torch"
b
#> object "toss"
#> sides: "roosevelt", "torch"
#> prob: "0.48", "0.52"
#> total tosses: 10
#> num of roosevelt: NA
#> num of torch: NA``````

Because, in general, it does not make sense to replace if index is out of the original length, we can add a `stop()` condition:

``````"[<-.toss" <- function(x, i, value) {
if (value != x\$coin\$sides[1] & value != x\$coin\$sides[2]) {
stop(sprintf('\nreplacing value must be %s or %s',
x\$coin\$sides[1], x\$coin\$sides[2]))
}
if (i > x\$total) {
stop("\nindex out of bounds")
}
x\$tosses[i] <- value
make_toss(x\$coin, x\$tosses)
}``````

Now we cannot replace if index is out of the original length:

``````set.seed(3752)
b <- toss(dime1, times = 5)
b\$tosses
#> [1] "roosevelt" "roosevelt" "roosevelt" "torch"     "torch"

# replacement
b[10] <- "torch"
#> Error in `[<-.toss`(`*tmp*`, 10, value = "torch"):
#> index out of bounds``````

## 7.3 Extraction Method

What if you want to know what is the value of toss in position 3? You could type something like this:

``````b\$tosses[3]
#> [1] "roosevelt"``````

Or you could create an extraction method that allows you to type `x[3]`. The function behind this expression is the extraction `"["()` function. We can also create a extraction function for a given class.

``````"[.toss" <- function(x, i) {
x\$tosses[i]
}``````

Test it:

``````set.seed(3752)
b <- toss(dime1, times = 5)
b\$tosses
#> [1] "roosevelt" "roosevelt" "roosevelt" "torch"     "torch"
b[1]
#> [1] "roosevelt"``````

## 7.4 Is `"toss"`

Another common type of function for an object of a given class is `is.class()`-like functions: e.g. `is.list()`, `is.numeric()`, `is.matrix()`. This type of functions allow you to test or check whether an object is of a given class.

We can create our own `is.toss()` to check whether a given R object is of class `"coss"`. Here’s how to define such a function:

``````is.toss <- function(x) {
inherits(x, "toss")
}

is.toss(b)
#> [1] TRUE
#> [1] FALSE``````

R comes with generic Math methods (see `?Math`). Among these generic methods we can find the `"+"` operator. This means that we can define our own plus method for objects of class `"toss"`. The idea is to be able to call a command like this:

``````# toss object
b <- toss(dime1, times = 5)

b + 5``````

Here’s one implementation of `"+.toss()"` in which the first argument is an object of class `"toss"`, and the second argument is a single positive number that will play the role of additional tosses:

``````"+.toss" <- function(obj, incr) {
if (length(incr) != 1 | incr <= 0) {
stop("\ninvalid increament (must be positive)")
}
more_flips <- toss(obj\$coin, times = incr)
make_toss(obj\$coin, c(obj\$tosses, more_flips\$tosses))
}``````

Remember that `"+"` is a binary operator, which means that writing a `"+"` method requires a function with two arguments. Let’s try it:

``````# add four more tosses
mycoin <- coin()
seven <- toss(mycoin, times = 7)
seven
#> object "toss"
#> prob: "0.5", "0.5"
#> total tosses: 7
#> num of tails: 3``````

Let’s add a couple of more tosses to `seven`:

``````# two more flips
seven + 2
#> object "toss"
#> prob: "0.5", "0.5"
#> total tosses: 9
#> num of tails: 5

# three more flips
seven + 3
#> object "toss"