A estas alturas, te habrás dado cuenta de que en Ruby no se declaran los tipos de variables o métodos: todo es un objeto. Los objetos en Ruby pueden ser modificados: siempre se pueden añadir métodos a posteriori. Por lo tanto, el comportamiento del objeto, puede alejarse de aquel suministrado por su clase.
En Ruby, nos fijamos menos en el tipo (o clase) de un objeto y más en sus capacidades. Duck Typing se refiere a la tendencia de Ruby a centrarse menos en la clase de un objeto, y dar prioridad a su comportamiento: qué métodos se pueden usar, y qué operaciones se pueden hacer con él.
Se llama "Duck Typing" porque está basado en el Test del Pato (Duck Test):
Si camina como un pato, nada como un pato y hace "quack", podemos tratarlo como un pato. James Whitcomb Riley
Veamos el siguiente ejemplo:
# Comprobamos qué objetos responden al método t_str
puts ('Una cadena'.respond_to? :to_str) # => true
puts (Exception.new.respond_to? :to_str) # => true
puts (4.respond_to? :to_str) # => false
Este ejemplo, es una forma simple de la filosofía "pato typing": si un objeto hace quack como un pato (o actúa como un string), pues trátalo como un pato (o una cadena). Siempre hay que tratar a los objetos por lo que pueden hacer, mejoer que hacerlo por las clases de las que proceden o los módulos que incluyen.
Las excepciones (Exceptions) son un tipo de string que tienen información extra asociada con ellas. Sin embargo, aunque ellas no son una subclase de String
, pueden ser tratadas como tales.
class Pato
def quack
'Quack!'
end
def nadar
'Paddle paddle paddle...'
end
end
class Ganso
def honk
'Honk!' # onomatopia de un pato
end
def nadar
'Splash splash splash...'
end
end
class GrabadoraDePatos
def quack
play
end
def play
'Quack!'
end
end
# En este método, la Grabadora
# se comporta como un Pato
def haz_quack(pato)
pato.quack
end
puts haz_quack(Pato.new)
puts haz_quack(GrabadoraDePatos.new)
# Para este método, el Ganso
# se comporta como un Pato
def haz_nadar(pato)
pato.nadar
end
puts haz_nadar(Pato.new)
puts haz_nadar(Ganso.new)