In this session we'll discuss S4 methods. It's a continuation of the previous session on S4 classes. Let's start by load the GenomicRanges library. There's going to be a few examples we're going to pick from there. So a method is a function that allows you to run different sets of code based on different values of the argument. That sounds very fancy, in reality it's pretty simple. Over here in the R console I've written a small function called mimicMethod that looks very much like you want to think about an S4 method or any kind of method. So it's a function that takes a single argument x, and it basically consists of a lump of if statements. It says that if x is a matrix, run some code that's called method1. If x is a data.frame, run some code that's called method2. If x is an IRanges, run some code that is called method3. In this case, mimicMethod is what is know as a generic function, because this is where the kind of if statements happens. x is the main argument. We're doing dispatching on x. It means that we examine x, and we use the class of x to tell us which piece of code to run. So that sounds a little fancy. Let's take an example. And let's look at as.data.frame. So when we look at the printout for as.data.frame, you can see that there's something with a standard generic and something with a method, and this identifies it as a S4 method. You can see that it was made into an S4 method in the packet called BiocGenerics. And there's a version from base R that we can access with base::as.data.frame that is not an s4 method. It looks differently it is actually an S3 method as you can see there's something called UseMethod inside the function definition. But BiocGenerics redefines this method as an S4 method. This is what happens when you get a lot of printout in the beginning. Let me scrolled back up a little bit. It says here the following objects are masked from package:base, and in here we have as.data.frame. So this printout we get when we load genomic ranges, or it actually happens when we load BiocGenerics, is just telling us that as.data.frame is being redefined as an S4 generic. So as.data.frame is going to examine its argument and decide which piece of code to run. So let's see how many pieces of code we have to find. We look at that by the showMethods function. And we see that it's defined for a number of different classes that are all Bioconductor classes. So we are going to do dispatching on the argument called lowercase x and it runs different types of code depending on which class x has. It doesn't have strictly to be different kinds of code. Some of these things might be the same code. [COUGH] So how do we actually see the code? We use the function getMethod and now we have to say what method is it we are interested in. It's as.data.frame, and what is the value of x. So I can say GenomicRanges, and out is the function definition or method definition. Now note in the thing I said here with getMethod I didn't really tell it that it was the argument x that was GenomicRanges. The foolproof call to getMethod says I have to do something known as signature and I say that x is x as GenomicRanges. So how do we get help on methods? That is a little irritating. It's irritating because you have to type a lot to get to the right help page. So let's go back here and look at the showMethods. The problem with S4 methods is that each of these specific functions that are listed here, or specific instances of methods that are listed here, can have its own help page and its own package. So you have write not only am I looking for help on as.data.frame but also as.data.frame when run on a, let's say, capital DataFrame. So there's two ways of doing it. They are very similar to the way we get help for S4 classes. We just say method, colon. Now we have to have some quotes. So we're learning for as.data.frame and a comma, and then say we want to look for the DataFrame where x is a DataFrame. And out comes a help page that really mostly talks about the capital DataFrame class and perhaps somewhere says that there's an as.data.frame near here. You can also, instead of having this ugly method?, we can just say ?as.data.frame, the class we want to examine, and then -method. Not even method. Method. [COUGH] Or we want something else, GenomicRanges. So we have to type a lot, and this becomes even worse if we are dispatching on multiple arguments. So in as.data frame, you can see that we just have functions that defined for different values of x. So we are only dispatching on the argument x. Let's look at something more complicated. Let's show the methods for findOverlaps. This is a function we love in this class. [COUGH] So findOverlaps have two main arguments. It has a query and a subject. [COUGH] And it does dispatching on both query and subject. And depending on different combinations of query and subject, it's going to run different types of code. [COUGH] So now we get into this problem where we, well, not a problem, but now we have to use the signature. We have to write a lot in order to see, so if we want to get the method, We now use signature and now we have to say that the query, Could be a Ranges and the subject could be a RangesList. [COUGH] Okay, you can see up in the showMethod output that there wasn't a combination like this, but there's a combination from Ranges and Ranges. We see the code, and in a similar way if we want to get some help on it, we say ?findOverlaps, and now you have to know the order in which things are. So now we have to set Ranges, cover Ranges-method. And we get to the right help page. So S4 methods are really powerful if you are writing a package where you want objects in the package to work like basic R functions. That's the case for IRanges and GenomicRanges, and we know when we like those classes and the functionality just works. The drawbacks to S4 methods is that it's hard to use the help system. It's hard to see the code. They are hard to debug. And so I think they can be a little bit of a pain. For the use case that you have with GenomicRanges and IRanges, it's hard to imagine doing what they're doing without using S4 methods. But many packages that does analysis, it's not so clear what people gain from using S4 methods. In my own work, I use S4 classes extensively in my own methods development. I use S4 methods quite sparingly.