Duck Typing
Talvez você já tenha notado, que em Ruby não declaramos os tipos de variáveis ou métodos – tudo já é algum tipo de um objeto. Objetos em Ruby (ao contrário dos objetos em outras linguagens orientadas a objeto) podem ser individualmente modificados. Você sempre pode adicionar métodos em um objeto. Em Ruby, o comportamento ou a capacidade de um objeto, pode se diferenciar dos fornecidos pela sua classe.
Se um objeto anda como um pato e fala como um pato, então o interpretador Ruby está feliz em tratá-lo como se fosse um pato.
Considere o seguinte exemplo.
1 # Verificar se o objeto defini o método to_str 2 puts ('Uma string'.respond_to? :to_str) # => true 3 puts (Exception.new.respond_to? :to_str) # => false 4 puts (4.respond_to? :to_str) # => false
O exemplo acima é o exemplo mais simples da filosofia Ruby de Duck Typing: se um objeto faz “quack” como um pato (ou age como uma string), basta ir em frente e tratá-lo como um pato (ou uma string). Sempre que possível, você deve tratar objetos de acordo com os métodos que ele possui, ao invés, de definir as classes a partir do que eles herdam ou módulos que incluem.
Agora, considere as três seguintes classes – Pato, Ganso e PatoDonald. Programa p036duck.rb
1 class Pato 2 def quack 3 'Quack!' 4 end 5 6 def nadar 7 'nadando nadando nadando...' 8 end 9 end 10 11 class Ganso 12 def grasnar 13 'Grasnando!' 14 end 15 16 def nadar 17 'Splash splash splash...' 18 end 19 end 20 21 class PatoDonald 22 def quack 23 play 24 end 25 26 def play 27 'Quack! Sou o Pato Donald!' 28 end 29 end 30 31 def faz_quack(pato) 32 pato.quack 33 end 34 puts faz_quack(Pato.new) 35 puts faz_quack(PatoDonald.new) 36 37 def faz_nadar(duck) 38 duck.nadar 39 end 40 puts faz_nadar(Pato.new) 41 puts faz_nadar(Ganso.new)
Se você consultar o código abaixo:
1 def faz_quack(pato) 2 pato.quack 3 end 4 puts faz_quack(Pato.new) 5 puts faz_quack(PatoDonald.new)
Um método que disse a um Pato para fazer quack funciona quando recebe um PatoDonald, graças ao Duck Typing. O mesmo pode ser observado no seguinte código:
1 def faz_nadar(pato) 2 pato.nadar 3 end 4 puts faz_nadar(Pato.new) 5 puts faz_nadar(Ganso.new)
Quando um método que diz para um Pato nadar recebe um Ganso, ele funciona.
Este material tem como base o tutorial do RubyLearning.com de Satish Talim e foi traduzido por membros do GURU-SP com a permissão do autor.
Ajude o RubyLearning participando em algum dos cursos pagos ou fazendo uma doação para o projeto