Substituição de método com super ()

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á.