Si è già detto che in
Ruby non è necessario dichiarare i tipi di variabili e di metodi poiché ogni cosa è trattata come un oggetto. Gli oggetti
Ruby, diversamente da quelli trattati dagli altri linguaggi di programmazione orientati agli oggetti, possono essere modificati individualmente. In
Ruby, il comportamento o le capacità di un oggetto possono essere deviati da quelli inviati dalle sue classi e inoltre si dà più importanza alle capacità di un oggetto che al tipo o classe dello stesso.
Di conseguenza,
Duck Typing indica che un oggetto è definito da cosa esso può fare, non da quello che rappresenta.
Duck Typing si riferisce alla tendenza di
Ruby di preoccuparsi meno delle classi di un oggetto che dei metodi che in esso si posono chiamare e quali operazioni possono essere realizzate in esso. In
Ruby, potremmo usare
respond_to o passare semplicemente un oggetto al metodo e sapere che sarà sollevata una eccezione se il metodo è usato impropriamente. Se un oggetto si muove come una papera e si esprime come una papera, l'interprete di
Ruby lo tratterà come tale.
Si consideri l'esempio seguente:
<span style="font-size:1.0em">
# controlla se un oggetto definisce il metodo to_str
puts ('A string'.respond_to? :to_str) # => true puts (Exception.new.respond_to? :to_str) # => true
puts (4.respond_to? :to_str) # => false
</span>
L'esempio appena visto è il più semplice della filosofia
Ruby, conosciuta come
Duck Typing: se un oggetto starnazza come ad una papera (o agisce come una stringa), allora la si consideri e la si tratti come una papera (o una stringa). Quando possibile, si possono trattare gli oggetti secondo i metodi che essi definiscono, piuttosto che le classi che essi ereditano o dai moduli che essi includono. Le eccezioni, per istanza, sono essenzialmente stringhe che hanno informazioni extra associate ad esse. Ecco un esempio (
p036duck.rb) che considera tre classi,
Duck, Goose e
DuckRecording:
<span style="font-size:1.0em">
class Duck
def quack
'Quack!'
end
def swim
'Paddle paddle paddle...'
end
end
class Goose
def homk
'Hock!'
end
def swim
'Splash splash splash...'
end
end
class DuckRecording
def quack
play
end
def play
'Quack!'
end
end
def make_it_quack(duck)
duck.quack
end
puts make_it_quack(Duck.new)
puts make_it_quack(DuckRecording.new)
def make_it_swim(duck)
duck.swim
end
puts make_it_swim(Duck.new)
puts make_it_swim(Goose.new) </span>
Se ci si riferisce al codice sottostante:
<span style="font-size:1.0em">
def make_it_quack(duck)
duck.quack
end
puts make_it_quack(Duck.new)
puts make_it_quack(DuckRecording.new) </span>
Un metodo che dice a
Duck di esprimersi, lavora quando viene dato un
DuckRecoding, a seconda dell'input immesso. Ecco un esempio di metodo che dice a
Duck di nuotare quando riceve la parola
Goose:
<span style="font-size:1.0em">
def make_it_swim(duck)
duck.swim
end
puts make_it_swim(Duck.new)
puts make_it_swim(Goose.new) </span>
"Traduzione e adattamento a cura di Francesca Beatrice Cice. La versione originale del tutorial di Satish Talim può essere trovata su
rubylearning.com"