Ruby gives methods the ability to call up to the superclass definition of themselves. Or it may not be a parent class definition; it might call up to a definition in a module included further up the ancestor chain. Either way, it’s an elegant way to build on the functionality of class ancestors.
But sometimes you may not know if there is a superclass method to be called. For instance, you may be writing a module. You want the module methods to delegate back to their superclass definitions if those definitions exist; but you don’t want the code to crash with a NoMethodError if they don’t exist. What to do?
As always, Ruby gives us the tools we need.
defined? to the rescue:
module Stuff def foo puts "In Stuff#foo" if defined?(super) puts "Calling super" super else puts "No super" end end end module OtherStuff def foo puts "In OtherStuff#foo" end end class NoSuper include Stuff end NoSuper.new.foo # >> In Stuff#foo # >> No super class WithSuper include OtherStuff include Stuff end WithSuper.new.foo # >> In Stuff#foo # >> Calling super # >> In OtherStuff#foo
defined? is a built-in Ruby operator (not an ordinary method!) which can tell you if a given method or variable has been defined. It also works for determining if a super method exists somewhere in the ancestor chain. Use
defined?(super) to write generic modules that play well with others.