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
endEt voici comment l’utiliser:
base = Base.new
base.foo("Hello")
#=> Hello from BaseMaintenant 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
endVoici ce que ça donne:
child = Child.new
child.foo("Hello")
#=> Hello from Base
#=> Hello from ChildIl faut noter que:
- La méthode éponyme
foode 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
superdans 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
endCette 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
endEt cette fois-ci, ça fonctionne parfaitement:
child = Child.new
child.foo("Hello", "world")
#=> Hello from Base
#=> Hello world from ChildÀ demain.