CSC/ECE 517 Fall 2007/wiki1b 2 22
Introduction - method_missing
method_missing: This method is called whenever someone tries to call a method in your object that doesn't exist.
Examples
1. Object composition
class SimpleCallLogger def initialize(o) @obj = o end def method_missing(methodname, *args) puts "called: #{methodname}(#{args})" a = @obj.send(methodname, *args) puts "\t-> returned: #{a}" return a end end
This object "intercepts" all method calls made to it, prints out a message and forwards on the method call to an internal object using the 'send' method, without knowing anything about the object passed to it. It can be used to debug some code without littering it with print statements. [1]
2. factorial
Let's create a Computer class that contains a factorial method (you know the famous n! thing).
class Computer def factorial n raise ArgumentError if n < 0 f = 1 n.downto(1) do |i| f = f * i end f end end
computer = Computer.new puts computer.factorial(4)
We would like to use some notation close to the usual notation:
computer = Computer.new puts computer._4!
Obviously, we cannot create methods for every integer, to do it we use the method_missing.
def method_missing(meth, *args) meth.to_s =~ /_([0-9]*)!/ return super if ! $1 factorial($1.to_i) end
If we use the special notation (_<digits>!) the method_missing implementation extracts the number, from the method name, and calls the factorial method to get the result. Each time and for any method the same processing happens.