La méthode super en Ruby
Aujourd’hui un aperçu de la méthode super
pour les débutants en Ruby.
C’est une méthode dont le comportement peut surprendre si vous venez
de certains autres langages…
Pour étudier le comportement de super
il va nous falloir utiliser
l’héritage. Voici une classe de base toute simple:
class Base
def foo(bar)
puts "#{bar} from Base"
end
end
Et voici comment l’utiliser:
base = Base.new
base.foo("Hello")
#=> Hello from Base
Maintenant créons une classe fille qui hérite de Base
et
redéfinissons la méthode foo
:
class Child < Base
def foo(bar)
super
puts "#{bar} from Child"
end
end
Voici ce que ça donne:
child = Child.new
child.foo("Hello")
#=> Hello from Base
#=> Hello from Child
Il faut noter que:
- La méthode éponyme
foo
de la classe de base n’est pas appelée implicitement. Il faut le faire explicitement avecsuper
. - On est pas limité à un constructeur, on peut appeler
super
dans une simple méthode. - Dans ce cas précis, pas besoin de passer l’argument
bar
à la méthodesuper
, c’est fait automagiquement.
Allons plus loin et faisons faire plus de choses à la méthode foo
de la
classe fille:
class Child < Base
def foo(bar, baz)
super
puts "#{bar} #{baz} from Child"
end
end
Cette fois-ci la magie n’opère plus et nous avons droit à une belle erreur:
child = Child.new
child.foo("Hello", "world")
#=> super.rb:2:in `foo': wrong number of arguments (2 for 1) (ArgumentError)
Ruby nous signale que la méthode foo
de la classe Base
a reçu 2
arguments, alors qu’elle n’en attendait qu’un seul ! Pourquoi, alors que
nous n’avons même pas passé un seul argument ? Parce que super
, sans
arguments, prends tous les arguments passés à la méthode dans
laquelle il se trouve et les envoient tous vers la méthode éponyme de la
classe de base…
Alors comment on s’en sort ? Très simplement en passant à super
les
paramètres que l’on veut:
class Child < Base
def foo(bar, baz)
super(bar)
puts "#{bar} #{baz} from Child"
end
end
Et cette fois-ci, ça fonctionne parfaitement:
child = Child.new
child.foo("Hello", "world")
#=> Hello from Base
#=> Hello world from Child
À demain.