Следуйте определению методов, чтобы понять, почему это происходит.
Сначала вы определяете Example1::example
в определении класса Example1
.Он записывает строку в консоль.
Затем вы расширяете ExampleAliaser
.Когда вы вызываете Example1::do_example_alias
, вы затем создаете псевдоним метода example
до origin_example
и переопределяете метод example
, чтобы записать в консоль другую строку и вызывать origin_example
.
Затем вы определяетекласс Example2
для наследования от Example1
, для которого теперь определены два метода: origin_example
и example
.Когда вы звоните Example2::do_example_alias
, вы называете метод example
до origin_example
.Но помните, что example
уже был переопределен для вызова origin_example
.Таким образом, Example2::example
будет вызывать себя до тех пор, пока вы не исчерпаете место в стеке.
Если вы хотите избежать двойного псевдонима, вы можете включить некоторый тип защиты в do_example_alias
:
def do_example_alias(prefix = :origin)
unless methods.include?("#{prefix}_example")
# do the aliasing
end
end
Вы также можете undef :method_name
в подклассах удалить методы, которые вы больше не хотите определять.