Ruby Tutorial | Metaprogramming in Ruby - Method Missing

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] what's up everyone steven here from techmaker.tv in this episode i want to do a little bit better explanation of method missing in ruby so yesterday i did an episode where i was trying to do some meta programming stuff and i think i got a little tripped up over some of the code actually which sort of makes sense when you're dealing with meta programming it's easy to do and i thought i would do a simpler explanation here just to make it more obvious what's going on with the method missing stuff in case i confused anybody yesterday before we get started be sure to give the video a thumbs up at the end if you do like this video and also go ahead and subscribe to the channel we're putting out this kind of content every day and i don't want you to miss out on anything with that said let's go ahead and jump into doing a little bit of coding directly in irb and then we'll crack open a file here in a couple of minutes and get some a little bit a little bit more in-depth stuff going all right so first of all let's open up irb and i'm going to create a kind of a placeholder class my go to is just dog it's not going to have any methods on here and let's try let's create a new dog dog is dog dot new and let's try to call a method on it so let's call dog.bark and we're going to get this no method error undefined method bark for dog now this obviously is a very common error if you've done any ruby programming at all you've seen this probably all the time you've probably seen a lot of undefined method something for nil class that's a very common one something like nil.bark undefined method bark for nil class so i'm going to clear my screen and call dog.bark again just so we have that here so what you may not know is that whenever you try to call a method on an object that where the method does not exist what happens internally in the object is there's a method that gets run called method missing and by default method missing method missing excuse me raises this no method error so this is the output of method missing and so we can try to call method missing so we could try to say like dog.method method missing and we're going to get this error that there's a private method that we're trying to call so you can't normally explicitly call that so in ruby there's sort of a hack that you can do to call private methods i some people do this all the time some people don't do it i don't really do it very much but you can do this you can say dog.send and this is actually going to call the private method so you can send this message method method missing and then we can pass it the message we want to send and so now you're going to get the same exact error that you get above which is undefined method bark called for dog okay so let's play with this a little bit more so i'm gonna clear my screen here and um what we can do is let's open up that dog class again and let's write a method method missing um method missing it's going to take the name of the method that it's trying to call and we can give it the splat operator with some args i think you can also do a block probably but we're not going to worry about that here and then instead of raising an error i'm just going to say puts method name called with and then we'll just do args like that and end and end so then we do dog equals dog.new and we can do dog.asdf and we basically get method asdf asdf called with an empty array we can say um hello there and the number nine and you get method hello called with there and the number nine so um that's basically how the method missing works so now if we call any method that doesn't exist [Music] it's going to be passed along to method missing so but i want to illustrate that if you call a method that does exist it it doesn't do that and i think that's kind of obvious but i just want to make sure that i show it so like if we do you can define a method directly on an object so this is also kind of a weird thing you can do in ruby but i'm instead of opening up the class i can actually just define a method on this dog so i can say def dog dot uh bark and then we can say uh puts rough like that and then if i say dog dot bark i get rough and then you know anything else is going to trigger that method missing method okay so i've got a couple more steps here and it's going to get to a more solid point so i'm going to suggest that if you watch this if you were confused at all yesterday by the episode which is totally understandable i was slightly confused watch this and then go back and watch that again it might be a little bit frustrating because it goes in circles and stuff but uh it kind of it'll make more sense so with that said let's open up this dog class one more time and i want to do something it's gonna we're also gonna define well let's start with defining a constant or a uh yeah so i'm gonna create a constant and it's gonna have some symbols in it and so it's gonna be like bark walk run eat and maybe that's good enough and then we'll do a method missing and same thing so it'll be name and splat args and what we're going to do is say um unless so if um name let's say actions dot any and then we'll give this a block here action and then we'll say action equals name dot to sim like this so basically we're saying if any of the actions match this method name um we'll say uh puts and then uh calling this is really not a big deal how what we say here but executing and then we'll say uh name with and do args like that else super okay um let's see if we did that right this about as much as i'm going to do directly in the terminal i need to do this in a text editor so that i can see what the heck i'm doing but let's try this so if we do dog equals dog.new and then we do dog dot bark executing bark with an empty array put a string in there okay and then if i do dog dot asdf i'm going to get an undefined method asdf so now what we're basically doing is saying hey we know that there's people who are going to call these methods on this object and we're going to provide some sort of nice behavior for it but if somebody tries to call something that we don't know about let's just treat it as as we would always treat it it's going to raise a no method error because we just don't know what it is so sticking with the dog example let's go to an actual file over here which i've already set up dog.rb and i'm going to create a class dog and we're going to like kind of map out what a more realistic example would look like so this is kind of how you're actually sort of expected to do this most of the time in a professional setting so if we do something like actions equals bark and again this is i say professional setting but this is obviously still a very simplistic example bark walk run eat and then we can define our method missing again and let's say we're going to take a name and splat args and then in here what i want to do is say um let's see so we basically want to just put um and then we'll say name called with args i'm also going to do one thing really quick here i'm going to set up a rake file so i've published a video this morning on uh how to basically reload the the console so check that out i'm just going to paste this here we're going to load dog and we just need to change this to be the name of the folder we're in right now which is missing and let's give this let's give this a shot so um let's check on everything really quick i had a question mark right here and i just realized it and took that away we don't need a question mark okay so let's go over here and run a rake console and uh we should be able to now do dog equals dog dot new and dog.bark bark called with an empty array so no arguments and then asdf with a string asdf okay so what i want to do is take a look at um this method here so like if let's first of all let's just do um well let's do this let's define one method over here hello and then just puts hello so if we reload now and we dog is dog.nu dog.hello so i can actually introspect this object and say dog.responds to hello and um that's not the method respond i think there's no s there we go so that's the method dog.respond to hello is true and if we try that with something like bark we're gonna get false even though we are wanting it to respond to bark so the reason that this is important is first of all introspection is a big deal in developing in ruby and so some other developers are going to come along in the future and be looking at your object and trying to figure out what all it does and you want your object to tell the truth so if you have an object that responds to a handful of extra methods that aren't defined so they're called what you might call like a ghost method i think that's what they call it in the meta programming ruby book which i highly recommend if if you are responding to just a handful of methods you would like it to return true for those and then false for everything else if you're developing an object that is really like a magical object that will respond to any method you throw at it you basically want it to always return true or something like that so we need to actually teach our object how to to respond and we can do that over here so we're going to write a new method and again this is a built-in method that we're overriding so we're going to say def respond to missing and this time we do need a question mark and we'll say name and i think it takes a second so this is include private equals false so this is basically uh again we're overriding a built-in method and this is just what it is so what we're going to do in here is basically say under what circumstances do we respond to missing or how do we respond in the event that someone asks us whether or not we respond to a method so it's kind of complicated but i think it'll make sense once we walk through it so essentially what we're going to do is what we did in our if statement while we were over in irb so i'm just going to say actions dot any and then we're going to check each of these actions so action and then we'll say uh action equals equals um name dot to sim so that's going to return true or false so do any of does the method that's being called match any of the actions that we have available up here so if that turns out to be true we want to say yes we do respond to this method otherwise let's just call super not super super okay then over here let's uh i'm going to clear and reload i'm really loving all the tips you guys are giving me so now let's do dog equals dog dot dog.new and we'll say dog.respond to and then we'll check like walk and it's true now if we check asdf it's false okay so the last little bit that we want to do because this is cool but it's actually still not quite right because if we do dog.asdf it actually does respond to asdf so what we need to do to make this really fully complete is basically say super unless respond to name okay and let's reload one more time dog equals dog dot new and then dog dog.sdf we're going to get an undefined method error and then if we do dog.walk we're going to get our method being called so this is pretty cool this may feel a little contrived and it is and the methods aren't really doing anything like i was saying you know what we did in the episode yesterday is a slightly more realistic example you know one of the things we could do and uh i'll just kind of from that's basically the episode up till here but just to kind of play around with it a little more uh we could do something like uh class uh living thing or like a living mechanism mechanics i don't know what do you call these things bark walk activities activities i don't know it doesn't even matter let's just do like then we'll do our eigen class and um we can come in here and now we can say like uh def walk um run and just leave it at that and then we can just puts walking puts running you'll see where we're going with this in just a second so what we can actually do is say and i'm going to get rid of this actions here and now what we can do is say respond to missing and we'll say activities respond to name okay and then here we're actually going to activities send name like this so reload dog equals dog dot new dog dot run uh dog dot walk dog dot eat and we're gonna get an undefined method eat so this is what i was kind of doing this is analogous to what i was doing yesterday because i have multiple classes using the same thing and i wanted them to all dynamically pick up the behavior as we change it so now if i come in here and i say dog or no so if i do def asdf and then uh puts just typing stuff so now if i come over here and i reload and i'm going to clear that as well oh hit the wrong thing um rake console and i hit the wrong button let me try it again and then we'll do dog equals dog.new dog.asdf so you know this is kind of cool if you had other classes that were consuming this activities in this way you could just add stuff to the activities and show up it's sort of like creating a like a faux superclass in a way in this specific context um that's not exactly what was happening yesterday with the uh the the library that i've been kind of working on for data analysis so anyway um this is all kind of interesting stuff it's kind of like it's a mental exercise in some ways it can be very practical in some situations but it's not a hammer for every nail basically so i really enjoy it but you know i don't actually use it all that much in like production code so definitely check out the meta programming ruby book though they go through some practical cases that do use it and it's pretty interesting so anyway that's pretty much it for this episode i hope you enjoyed it uh if you did please give it a thumbs up and subscribe to the channel as always and i will talk to you in the next episode
Info
Channel: Techmaker Studio
Views: 849
Rating: undefined out of 5
Keywords: ruby tutorial, metaprogramming, metaprogramming ruby, learn ruby, ruby programming, ruby for beginners, ruby programming tutorial, learn ruby programming, ruby tutorial 2020, learn to code, ruby programming language, ruby course
Id: AVfp6V-lEZo
Channel Id: undefined
Length: 18min 45sec (1125 seconds)
Published: Fri Aug 21 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.