Let us consider the following example:
1class Person
2 def greeting
3 puts "Hello"
4 end
5end
6
7class Person
8 def greeting_with_expression
9 puts "Hi,Hello"
10 greeting_without_expression
11 end
12
13 alias_method :greeting_without_expression, :greeting
14 alias_method :greeting, :greeting_with_expression
15endIn the example above Person#greeting is overridden using alias method. greeting_without_expression calls the actual greeting method.
With the advent of Module#prepend in Ruby 2.0 it allows you override a method in a class with a method from a module, and still access the class's implementation with super:
1module Greeting
2 def greeting
3 puts "!!! Hello"
4 super
5 end
6end
7
8Person.prepend(Greeting)Greeting module is prepended to Person. And now when you call:
Person.new.greetingYou will end up with:
SystemStackError: stack level too deepWhat happened on the background is that Greeting#greeting was called at first then it calls its super_method(Person#greeting_with_expression). At the end of execution of greeting_with_expression it calls the greeting_without_expression method which again calls Greeting#greeting due to method lookup. This creates a deadlock situation and results in stack level too deep error.
Learning from the above example is that you will not be able to combine Module#prepend and Module#alias_method. You can follow only one of these method if you want to overwrite a method at multiple levels.
Lookup for alias method and prepend when you come across stack level too deep error next time. Happy Coding !!!
