Ruby on Rails

Summarized using AI

The Magic of Ruby's method_missing

Kaylah Rose Mitchell • May 30, 2023 • online

In this insightful talk by Kaylah Rose Mitchell from the WNB.rb Meetup, the focus is on 'methodmissing', a powerful feature in Ruby that allows dynamic method handling at runtime. The session begins with an introduction to methodmissing, illustrating how it works through a simple code example involving a Dynamic class. Key points discussed include how Ruby’s interpreter searches for method definitions in the class and its superclasses, leading to a no method error when a method is absent. The talk explains how this behavior can be overwritten by defining a method_missing method within a class, enabling custom reactions to missing method calls.

Further exploration reveals real-world applications, such as the String Inquirer class in Rails, where methodmissing is effectively utilized to define methods dynamically at runtime. The importance of combining methodmissing with another related method, respondtomissing?, is highlighted to ensure that the system accurately recognizes the dynamic methods.

Mitchell cautions against excessive use of methodmissing, noting potential impacts on performance and code readability. The session emphasizes the nuances of metaprogramming in Ruby, suggesting that while methodmissing offers flexibility, it’s crucial to consider explicitly defined alternatives for clarity and maintainability. Overall, participants are encouraged to explore Ruby’s metaprogramming capabilities to better understand its potential and practical applications.

Key Points:

  • Introduction to method_missing and its role in dynamically handling methods.
  • Demonstration through a code example using a Dynamic class.
  • Explanation of how Ruby searches for methods in classes and superclasses.
  • Overview of the String Inquirer class in Rails showing practical usage.
  • The relationship between methodmissing and respondto_missing?.
  • Cautions about performance implications and maintainability when using method_missing.
  • Encouragement to explore Ruby metaprogramming further.

The Magic of Ruby's method_missing
Kaylah Rose Mitchell • May 30, 2023 • online

Discover the magic of method_missing and learn how to unleash its full potential in your Ruby applications. In this talk, we'll dive into the inner workings of method_missing and explore how it can be used to dynamically define methods on objects at runtime, handle missing method calls, and perform powerful metaprogramming tasks.
https://www.wnb-rb.dev/meetups/2023/05/30

WNB.rb Meetup

00:00:00.000 today we are going to talk about the
00:00:02.159 magic of method missing
00:00:06.720 my name is Kayla Rose Mitchell and I am
00:00:09.660 a software engineer from Central
00:00:11.099 California just outside the San
00:00:13.799 Francisco Bay Area
00:00:15.360 and you can find me on GitHub and
00:00:18.119 Linkedin at Kayla Rose
00:00:23.939 slide so what exactly is Method missing
00:00:29.160 let's take a look at a simple code
00:00:30.779 example consider our Dynamic class here
00:00:34.980 we are creating an instance of this
00:00:37.380 Dynamic class and calling the do
00:00:40.320 something method on that instance
00:00:43.620 we didn't Define that method in our
00:00:45.540 Dynamic class so when we call do
00:00:47.760 something we are going to get a no
00:00:50.100 method error
00:00:52.140 but where does this no method error come
00:00:54.960 from
00:00:59.460 when we call do something on our Dynamic
00:01:02.039 class object and dynamic class is an
00:01:04.559 arbitrary class name we can name this
00:01:05.939 anything we would like
00:01:07.380 the Ruby interpreter is going to look
00:01:09.479 for that class
00:01:10.860 excuse me it's going to look for that
00:01:12.479 method within the class
00:01:14.220 when it isn't found there it checks the
00:01:16.560 superclass
00:01:18.060 Dynamic class inherits from object class
00:01:20.640 we can see here
00:01:22.680 The Interpreter repeats the step of
00:01:24.420 checking for the method in that class
00:01:26.220 and upon not finding the do something
00:01:28.680 method we check the object's parent
00:01:31.799 class which is basic object that we can
00:01:33.720 see over here
00:01:35.180 it's in the basic object class that we
00:01:38.340 find method missing defined as a private
00:01:40.920 instance method
00:01:43.619 we can overwrite a call to basic objects
00:01:46.619 method missing by defining it in another
00:01:49.380 class
00:01:54.420 so this is what the method will look
00:01:56.520 like
00:01:57.780 the method missing accepts a method name
00:02:01.140 a collection of arguments
00:02:03.479 and if you haven't seen this before the
00:02:05.820 asterisk on arguments is the Splat
00:02:08.640 operator which allows us to pass
00:02:10.800 collections as arguments
00:02:13.160 method missing additionally accepts a
00:02:15.840 block but we won't be using that today
00:02:19.260 and in the body of the method we can
00:02:21.360 Define custom Behavior
00:02:24.180 foreign
00:02:27.980 now in our Dynamic class we have defined
00:02:31.560 method missing where we now want to
00:02:34.319 print a message along with the name
00:02:36.180 instead of erroring out
00:02:39.900 and as expected when we tell our object
00:02:42.420 to do something we see you tried calling
00:02:45.900 do something printed to my terminal
00:02:47.879 screen
00:02:55.739 okay let's take a look at some real
00:02:58.080 world applications of method missing
00:03:04.040 here we are looking at a code snippet
00:03:06.840 from the rails code base
00:03:09.239 in active support we have a class called
00:03:12.300 string Inquirer where we can see method
00:03:15.180 missing is defined
00:03:17.879 there's also the respond to Missing
00:03:20.159 Method that we will come back to in a
00:03:21.959 minute
00:03:24.060 so we expect to receive the method name
00:03:26.340 and arguments if the method name ends
00:03:29.040 with a question mark we compare the
00:03:30.900 method name to self
00:03:33.780 if the method name does not end with a
00:03:35.760 question mark we invoke super which will
00:03:37.860 go up through the parent classes until
00:03:40.260 we hit another method missing that will
00:03:42.420 either have custom logic that the method
00:03:44.700 call satisfies or that will air out
00:03:48.019 okay and how is this method missing used
00:03:51.599 here
00:03:55.860 well rails has excellent notes and
00:03:58.260 documentation to help us understand the
00:04:00.180 rails Magic
00:04:02.040 this method gives us a prettier way to
00:04:04.560 check for equality when we run our rails
00:04:07.379 applications
00:04:09.239 instead of writing
00:04:10.879 rails.am equals production we can Define
00:04:13.739 the interrogative method production at
00:04:16.500 runtime and check the environment
00:04:18.660 against that
00:04:21.840 and you can find a call to this in your
00:04:24.660 standard rails helper
00:04:30.740 when creating custom logic with method
00:04:33.479 missing we need to account for the
00:04:35.340 response to Method as well that we saw
00:04:38.100 in the string inquiry class in the
00:04:40.680 previous slides
00:04:42.720 in our example we can see that now our
00:04:45.360 object responds to do something but when
00:04:48.360 we run response to we get false even
00:04:52.500 though an instance of our Dynamic class
00:04:54.300 does in fact respond to do something
00:04:57.900 this is a pretty easy fix by
00:05:00.360 intercepting the call to respond to
00:05:02.699 missing
00:05:08.220 okay now we can see in our class we have
00:05:11.460 defined respond to missing
00:05:13.979 excuse me respond
00:05:16.259 yes respond to missing this also accepts
00:05:19.020 the method name and a collection of
00:05:20.880 arguments
00:05:23.100 and now when we call a response to and
00:05:25.500 pass a method it will work as expected
00:05:29.759 true is appropriate for our use case
00:05:31.740 here but I'd like to encourage you to
00:05:33.960 investigate how this method can be
00:05:35.940 written to accompany missing methods
00:05:37.740 that are more narrowly scoped
00:05:46.020 okay there are a few things to consider
00:05:48.539 when implementing method missing
00:05:55.139 method missing and dynamic dispatching
00:05:58.259 can slow down your application at
00:06:00.120 runtime so be aware of that
00:06:03.180 there are some other similar
00:06:06.180 meta programming methods and tools that
00:06:09.300 can be invoked and when we compare them
00:06:11.039 to Method missing and run things like
00:06:15.259 benchmarking we can see that there are
00:06:17.460 very clear runtime differences
00:06:20.220 so excessive use of method missing can
00:06:23.039 also make code harder to read understand
00:06:25.380 and maintain
00:06:28.139 it can also introduce runtime errors if
00:06:30.780 not handled properly
00:06:33.900 so we should take care when using method
00:06:36.660 missing and use it judiciously and
00:06:39.479 consider if there are more explicit and
00:06:41.580 straightforward Alternatives available
00:06:43.199 for handling method missing errors
00:06:48.180 method missing and other programming
00:06:50.400 meta programming tools and techniques
00:06:52.259 are not usually the best solution to a
00:06:55.800 problem but understanding what ruby can
00:06:58.560 do will help you unleash more potential
00:07:00.600 from the tools that do implement it
00:07:08.280 all right and I hope this inspires you
00:07:10.800 to dig into your current applications
00:07:12.539 and play with all of the meta
00:07:14.699 programming tools that Ruby has to offer
00:07:16.500 there are tons of books and blogs other
00:07:19.680 resources to help you dive in and better
00:07:22.139 understand what's possible with this
00:07:23.580 language
00:07:25.500 so please take a look at your favorite
00:07:26.940 libraries Frameworks and see where
00:07:29.580 method missed method missing is used to
00:07:32.160 make magic happen
Explore all talks recorded at WNB.rb Meetup
+20