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.





