When using method_missing
in Ruby, it's almost always a good idea to define respond_to_missing?
as well.
respond_to_missing?
takes two arguments; the name of the method we're checking (symbol
), and a boolean which indicates whether we should include private methods in our check (include_all
).
Now here's what I'm confused about: method_missing
doesn't take any arguments which might indicate to it whether it should call private methods or not, as respond_to_missing?
does. Furthermore, method_missing
gets called regardless of whether the original method call was in a public or private context, and regardless of what respond_to_missing?
returns for the given method in the appropriate context. So all operations of method_missing
are accessible publicly.
If that's the case, then what purpose does the second argument to respond_to_missing?
(include_all
) serve? Whether the given object responds to a missing method cannot be affected by the context in which the missing method was called, so why even have this argument at all?
method_missing() does not call public or private methods. method_missing() is called at the very end of the method lookup path when a method cannot be found. So comparing method_missing() and respond_to* is non-sensical. Why do you think that they have to operate the same way? respond_to?() never was symmetrical with method_missing() in the first place.
I think that
respond_to_missing?
has a second argument for the same reason thatrespond_to?
does. In both cases, it allows code to ask an object what methods it responds to in a way that respects method privacy. If used properly, it can help you encapsulate your objects better.You have pointed out a missing feature in
method_missing
, namely that it should have an argument that says whether the method was called in a public or private context. Maybemethod_missing
will have that feature some day. Until then, all functionality of the object that is implemented throughmethod_missing
will effectively be public, but you can still discourage people from using it in your documentation and viarespond_to_missing?
.