Handling Missing Methods

When Ruby tries to execute an undefined method (or, in object-oriented terms, when an object is sent a message that it cannot handle), the error causes the program to exit. You may prefer your program to recover from such an error. You can do this by writing a method named method_missing, with an argument to which the missing method’s name is assigned. This will execute when a nonexistent method is called:

nomethod1.rb

def method_missing( methodname )
   puts( "Sorry, #{methodname} does not exist" )
end
xxx        #=> Sorry, xxx does not exist

The method_missing method can also take a list of incoming arguments (*args) after the missing method name:

nomethod2.rb

def method_missing( methodname, *args )
      puts( "Class #{self.class} does not understand:
                   #{methodname}( #{args.inspect} )" )
end

Assuming the previous method_missing method were written into a class called X, you could now attempt to call any method on an X object, whether or not that method exists and whether or not it is passed any arguments. If, for example, you were to attempt to call a nonexistent method called aaa, first with no arguments and then with three integer arguments, the method_missing method would respond to the invalid method call and display an appropriate error message:

ob = X.new
ob.aaa            #=> Class X does not understand: aaa( [] )
ob.aaa( 1,2,3 )   #=> Class X does not understand: aaa( [1, 2, 3] )

The method_missing method could even create an undefined method dynamically so that a call to a nonexistent method automatically brings that method into existence:

def method_missing( methodname, *args )
       self.class.send( :define_method, methodname,
            lambda{ |*args| puts( args.inspect) } )
end

Remember that the lambda method turns a block (here the code between curly brackets) into a Proc object. This is explained in Chapter 10. The code is then able to pass this object as an argument to send, defining a new method with the same name as the methodname argument passed to method_missing. The effect is that when an unknown method is called on a Z object, a method with that name is created. Run the nomethod2.rb program, which contains this code:

ob3 = Z.new
ob3.ddd( 1,2,3)
ob3.ddd( 4,5,6 )

This gives the following output:

Class Z does not understand: ddd( [1, 2, 3] )
Now creating method ddd( )
[4, 5, 6]
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.226.251.70