 to get started. I'm going to talk about Hooks and Ruby today. My name is Craig Buchek. I have my own consulting firm called Buchtek. I do a lot of web development, Rails rescue projects, agile player coaching, and some DevOps. I do a lot of work with a company called Binary Noggin. We're going to have a few developers free in January. I do a podcast called This Agile Life. We talk about agile web development. We talk about people work here, not resources. I do some mentoring for Tech Institute for some underprivileged kids from St. Louis. And apparently you have to have a picture of your cat. So that's my cat Ivan. So what is a hook? The definition I'm going to use in this talk is a method that's called implicitly by Ruby and that we never call ourselves. Because it's implicit, it's going to be surprising and difficult to troubleshoot. I like to think of it as spooky action at a distance. It's a term from physics. Einstein actually. In the Ruby docs you'll see them referenced a few different ways. Sometimes they'll be called the hook. Sometimes they'll be called the callback. I didn't want to use the term callback because that's got some other meanings. A little distinct from what we're talking about today. And a lot of times you'll see the phrase Ruby calls this, which is an indicator that it's a hook. So there are hooks and callbacks in Rails and other libraries, but I'm just going to cover the ones in Ruby today. Who here is used initialize? Probably everyone. Notice that we never explicitly call initialize here. But it gets called anyway. So that's a hook. This is obviously the most commonly used hook in Ruby. But it does meet the definition. And that is initialize is defined on basic object, actually. So if you read the titles, I've got initialize there. I've got basic object and a hash sign that indicates that that can be found on the basic object class if you're looking up documentation. So what's happening behind the scenes when we call x.new? So x is an object of a class called class. So calling x.new calls new in the class class. It seems weird, but it's how every method call works. You have to kind of figure out this class is a class of class and that kind of thing. So this is basically what new looks like. It's actually written in C. This is roughly what it would look like if it was written in Ruby. So first we allocate some space and memory to hold the object. And then we take that object and we run the initialize on it. And we return the object. So meta programming is where you're most likely to use hooks. Two of the big ones are method missing and respond to missing. So method missing is on basic object. How many of you use method missing? Looks like a little more than half maybe. So we're allowing the calling of a method that we never define. This is probably the first tool you're going to reach for when you're doing meta programming. Active record uses method missing in a lot of different places. So the biggest downside of method missing is you can't search your code for the method you're looking for because it's just not in there. It's been dynamically found using this. A couple of things to note here. The method name is passed in as a symbol. And we use star args there as a second argument to method missing to gather up all the arguments into a single array. That star is called splat. And you can also pass a block. That's the only thing that doesn't come in the args array. I didn't use the block in this example, but I wanted to show that that's the signature you should always use for method missing. So whenever you use method missing, you should also use respond to missing. Although note that while method missing was on basic object, respond to missing is on object. So if you're not subclassing from object and you're only subclassing from basic object, you don't need to follow that rule. Otherwise, definitely follow that rule. So what does this do? If you ask an object, if it has a method, if it responds to a method and that method is not listed as a method in that class or on that object, then it's going to look at respond to missing. Before Ruby 91.2, we actually just had an override respond to. This way is a lot cleaner. It's also called when you call the method method. Also note that it takes a second argument there, respond to missing, include private false. So respond to takes a second argument that if you pass true, it will look for private methods as well as public methods. So you've got method missing. You've also got const missing, which is defined on module. Generally avoid this one. It seems pretty enticing, but it leads to some long-term problems that I don't find it to be worth it. So I would prefer just to use require or maybe use autoload. I don't know where I would quite draw the line. I know Rails likes to use this for autoloading. Remember that class names are constants. So if you're doing automatic class, trying to find what class is automatically const missing is what you would be using. So the inheritance life cycle. Four methods we use here to see when some inheritance type of thing is happening. So the first is module included. If you're including a module, this will get called. So in this example, we are including module A inside class B. And when that happens, exactly when that happens, A.included gets called with B passed in. And you can see what it would output in this case. Notice that it's self.included because it is on A itself. A itself is being included. There's no instance of A that is being included. So it's a class method there. Note that we didn't even need to new up a B. We just had to define the class and included got called. So this is good to use if you need to keep track of who is including you, what classes are including you. If you want to keep a registry of basically things that have included your module and you can provide some way to use that list in some other way. Similarly, if you're extending a class, you have basically the exact same thing. It's extended by extended. And except module B has to be a module here because you can't have a class, or you normally wouldn't have a class extending a module. So in Ruby 2.0, we added pre-pen, which is basically the same thing as include, but it adds it to the end of the module chain instead of the beginning. We used to use something for metaprogramming called alias method chain. And it seemed like a good idea when we started using it. And it ran into problems. It was just very hard to follow the flow. And we realized that module inclusion was a better way to do metaprogramming in most cases. But this works just like included. And again, we've got self-prepended. So this one's a little bit different because it's inherited. So it's class inheritance instead of modules. And there's not even a keyword for that. It's just class B less than A means class B inherits from A. And as soon as that happens, you've called the inherited method on A and B gets passed in. So there's hooks on method life cycles. We've got method added, method removed, and method undefined. So these aren't used too often because we don't dynamically add and remove methods too often. So removing a method, so if you use method remove, which leads to method removed hook being called, that will allow any of the superclass methods still to be called. If you call method undefined or if you just call undef on a method, it actually does the same thing as if you wrote a method that just returned or raised no method error. The only reason I can think why you would do that is if you're trying to look like an older version of Ruby or something like that. Removing a method, you would probably do that if you're dynamically adding methods and you want to start over and remove all the methods you had dynamically added. So you can also add methods to individual objects. Those are called singleton methods. And a class method is just a singleton method defined on a class itself. So there's equivalent life cycle methods for singleton. So if you do a method add to a class or some other object, you would get the singleton method added. So the next set of hooks I want to talk about are the implicit or strict conversion methods. So we've got a couple here. We've got two string str to int, to dur, int, to array, ary, to hash, to proc, and to enum. So these do have equivalents that are explicit and we'll talk about those in a second. So the implicit ones are used when we want to say something is like what it's converting to. So if you used to str, to str, you would want to use that only for something that not just could be shown as a string but should roughly act like a string. And the canonical case I came up with on that one is if you got a username class and you might want to compare it to a string. So if you're using double equals and the two things are different on the side and they can't compare, it'll call to str on the right side, try to get the right side to the same as the left side. So to str is also used when concatenating strings with a plus sign. And to ary is used when assigning to multiple left hand variables. So if you're doing a comma b equals one comma two, that would use to array if it needs to do some conversion. So we have equivalents. The explicit conversion functions, methods, which you guys are probably more familiar with. To s is for string, corresponds to str, to i, for integers, to a for arrays, to h for hashes. So that's usually, you would use those explicitly. There's a couple places where you wouldn't. And I want to point out the ampersand there is basically syntax to convert to a proc which calls to proc. So the exceptions here are if you are doing string interpolation with the hash and the curlies, that actually calls to s. I consider that implicit. But I believe MOTS and the other language developers say that there's some syntax indicating that you want a conversion. So it uses the explicit conversion operator. The same with the splat call. If you're using splat to convert to an array, it will use the 2a implicitly. Although I think that may have changed in Ruby 2.0, I did not get a chance to check that out. This is one that people don't think of when they are thinking about hooks. Of course. There's a couple different ways to have different types of numbers and number like things interact with each other. Ruby is a pretty good solution I found. The other one is called double dispatch which is what small talk uses. But this is one place where Ruby is not very much like small talk. So in our example here, we are defining a mathematical type. This is nothing like a quaternion. I don't even know how to pronounce it. But something you might want to define eventually. And this doesn't work because the line where it's trying to add self.I to other, it doesn't know how to add an other. So Ruby is nice enough to give you a hint that it says it can't be coerced to fix num. So that's hint that we need to add the coerced function to this class. So if we do that, we can do a push just to make sure that it's getting called. And it's important that what we turn in coerced. We have to return self as a second element. And technically, you don't have to return self. You have to return something that is the same value kind or that would have the same, let's see. If you were, let's say, a complex number and you gave it one, you would give it one plus zero I. Because it's equivalent even though it's a different type. So here we're just converting the first method. The other thing we get into something we can work with. And if you go back to the previous slide, we can add two of those together. So what's really happening under the covers here is if we have a Q1 that's a quaternion and an N that's just an integer, what's happening is the coerced function is going to run automatically for you. And it's going to set Q2 to the first thing that got coerced. Q1 is going to come back because we're returning self. And then it's going to do the addition. So this can happen with, I believe, any binary operator. It's defined on numeric. But anything you want to interact with binary operations that you want to work with numbers, matrixes, and vectors are another place where you would want to do that. So add exit is you can set a block or a proc to run when the program exits. So if you call add exit multiple times, they're running in reverse order that they're registered. And you can also check dollar bang to see if the program is crashed due to an exception. We do that in the example here. And in fact, you can print out the value of that. It's just a variable, global variable. If you require the English library, that's equivalent to dollar error info if you're not a fan of the pearl-like operators or globals. So we can convert that to a string. We're inspecting it here just like any other object. So thanks for coming. I've run a little early, so I will take questions from the audience if you got them.