2

I have a model that references and instance variable that is an instance of another class. I would like to delegate missing methods to that variable like this:

  def method_missing(method_name, *args, &block)
    if @other_class_instance.respond_to?(method_name)
      @other_class_instance.send(method_name, *args)
    else
      super
    end
  end

However, in the case that @other_class_instance doesn't respond, I'd like the app to terminate and get a full backtrace as a normal NoMethodError would. Instead, I just get one line error messages such as:

#<NoMethodError: undefined method `my_method' for #<MyClass:0x00000009022fc0>>

I've read in several places that if super isn't there, it will mess up Ruby's method lookup.

What am I missing so that if other_class_instance doesn't respond to the method, it will behave as if no method_missing method was created?

Update

Logan's answer takes care of this problem under the condition that the OtherInstance class does not also have a method_missing defined. In the case that it does (say for a Rails model), you could do something like the following:

 begin 
   raise NoMethodError.new method_name
 rescue => e
   logger.fatal e
   logger.fatal e.backtrace
   super
 end
Eric H.
  • 6,894
  • 8
  • 43
  • 62

2 Answers2

1

Why check respond_to? if you want the error to occur anyway? Just use send and NoMethodError will happen. See http://codepad.org/AaQYWjtQ - is this what you mean by the normal stack trace?

Logan Serman
  • 29,447
  • 27
  • 102
  • 141
  • Hmm, yea it is. I think I've got another situation where I'm checking for the method name in a hash and returning the value. Maybe this is an overuse of `method_missing`. It seemed really useful until I realized that `super` doesn't raise the error with a normal stack trace. http://www.alfajango.com/blog/method_missing-a-rubyists-beautiful-mistress/ – Eric H. Apr 18 '14 at 21:06
  • If you are using Rails, take a look at http://apidock.com/rails/Module/delegate if you want to forward method calls. – Logan Serman Apr 18 '14 at 22:00
1

Please check your @other_class_instance. From what you write I suppose that also this instance has respond_to? and method_missing are overwritten and produce the error message you see. If you write 'clean' test where @other_class_instance does not override standard method lookup, everything will work as you expected.

And yes, Logan is quite right, in your case just pass the call to the @other_class_instanse.send!

sergeych
  • 791
  • 7
  • 11