Unified method_exists method for ruby
There are loads of different ways to check whether an object (class or instance) contains a given method.
In fact, there are so many different ways that I spent some time working out what was what.
I started out testing each of the relevant Module methods on both a class and instance. This was followed up by testing each of the relevant Object methods on both a class and instance. The full test suite is here.
I summarised the results into a more compact test suite here.
I think I’m correct in stating that there’s no one way to check for the existence of a method (be it public, protected or private) on a class. However, the test results make it slightly easier to scan and create such a method – three variants none-the-less.
The same statement goes for uniformly determining the existence of a method on an instance. Once again the tests helped derive the three implementations here.
Combining these two imlpementations provides us with a uniform method to determine whether the receiver contains a method represented by method_sym.
class Object def method_exists?(method_sym) methods = public_methods + protected_methods + private_methods methods.include?(method_sym.to_s) end end class Class def method_exists?(method_sym) methods = public_instance_methods + protected_instance_methods + private_instance_methods methods.include?(method_sym.to_s) end end class Foo def foo; end; public :foo def bar; end; protected :bar def baz; end; private :baz end require 'test/unit' Class.new(Test::Unit::TestCase) do def assert_not(expr) assert ! expr end def assert_method_exists_is_working(receiver) [:foo, :bar, :baz].each do |sym| assert receiver.method_exists?(sym) assert receiver.method_exists?(sym.to_s) end assert_not receiver.method_exists?(:made_up_method) assert_not receiver.method_exists?('made_up_method') end def test_class assert_method_exists_is_working(Foo) end def test_instance assert_method_exists_is_working(Foo.new) end end
What’s the point you ask? I genuinely have no idea. I’m sure there was one when I started but then my compulsiveness took over and I had to finish for no other reason than to finish.