Uma das coisas que adoro no Ruby é a capacidade de substituir facilmente um comportamento de método por algo seu.
class MyClass
def old_method(arg)
puts "default behavior -> #{arg}"
end
end
class MyNewClass < MyClass
def old_method(arg)
puts "new behavior #{arg}"
end
end
MyClass.new().old_method("example1") # default behavior -> example1
MyNewClass.new().old_method("example1") # new behavior -> example1
Mas, como todos sabemos, devemos ter cuidado porque esse método pode estar fazendo algo que você não previu, levando você a uma armadilha. Uma das coisas que devemos sempre considerar é invocar o método super () dentro de nossa implementação, que se refere ao comportamento do método original.
class MyNewClass < MyClass
def old_method(arg)
puts "new behavior #{arg}"
super(arg)
end
end
MyNewClass.new().old_method("example2")
# new behavior -> example2
# default behavior -> example2
É comum não saber se um método já foi definido. Nesse caso, chamar o super () resultaria em um NoMethodError: super: nenhum erro do método da superclasse . Para resolver essa incerteza você pode usar o definido? operador para verificar a existência de um super método.
class MyNewClass < MyClass
def method_without_super(arg)
puts "no super -> #{arg}"
super(arg) if defined? super
end
end
MyNewClass.new().method_without_super("example3")
# no super -> example3
Uma coisa que a maioria das pessoas não sabe é que Ruby pode passar automaticamente os parâmetros do método para seu super.
class MyNewClass < MyClass
def old_method(arg)
puts "new behavior #{arg}"
super
end
end
MyNewClass.new().old_method("example4")
# new behavior -> example4
# default behavior -> example4
Ao chamar o super sem nenhum parâmetro, o Ruby obterá todos os parâmetros anteriores e os passará ao longo da chamada super () .
Uma pegadinha rápida sobre isso. Se você estiver usando a assinatura define_method (), este atalho de parâmetro não funcionará.