вівторок, 18 вересня 2007 р.

Качина типізація

Латентна, неявна або качина типізація (калька з англ. Duck typing) - вид динамічної типізації, яка використовується в деяких мовах програмування (Smalltalk, Python. Ruby, Boo), коли значення змінної визначає, те що вона може робити. Тобто є об'єкт, який реалізує інтерфейс, якщо він містить всі методи цього інтерфейсу, незалежно від зв'язків в ієрархії наслідування.
Англійська назва посилається на "качиний тест" (duck test) - "If a bird looks like a duck, swims like a duck and quacks like a duck, then it's probably a duck." ("Якщо птах виглядає як качка, плаває як качка і крякає як качка, це ймовірно і є качка").
Качина типізації піклується тільки про ті аспекти об'єкта, які використовуються, замість типу об'єкту безпосередньо.Наприклад, у мові без качиної типізації, можна створити функцію яка бере об'єкт Duck (Качка) і викликає його методи swim (плавати) quack (крякати). У мові з качиною типізацією, еквівалентна функція може взяти об'єкт будь-якого типу і викликати методи "плавати" і "крякати". Якщо об'єкт немає методів до яких звертаються, функція сигналізує run-time error (помилку виконання) .
Качина типізація - це фундаментальна частина мови програмування Ruby. Можна відмітити Ruby, не оголошує види змінних чи методів - все є тільки деяким видом об'єкту. Об'єкти Ruby (на відміну від об'єктів у деяких інших об'єктно-орієнтованих мовах) можуть бути змінені індивідуально. Ви завжди можете додавати методи до об'єкта. В Ruby поведінка і можливості об'єкту можуть відрізнятися від тих, що забезпечуються його класом.
В Ruby ми залежимо менше від типу (або класу) об'єкту і більше від його можливостей (методів). Відтепер, качина типізація має на увазі тип об'єкту, як те що з ним можна зробити, а не те, чим є об'єкт. Качина типізація посилається на тенденцію Ruby менше турбуватися про клас об'єкта, і більше концентруватися на його методах.
Якщо об'єкт плаває як качка і крякає як качка, то інтерпретатор Ruby щасливий розглядати його, ніби то це качка.
Розглянемо наступний приклад:
# Check whether the object defines the to_str method
puts ('A string'.respond_to? :to_str) # => true
puts (Exception.new.respond_to? :to_str) # => true
puts (4.respond_to? :to_str) # => false

Вищеописаний приклад - це найпростіший приклад філософії "качиної типізації"в Ruby, якщо об'єкт крякає як качка (або діє як рядок(String)), розглядати його як качку (або рядок(String)). При першій-ліпшій можливості, ви повинні розглядати об'єкт згідно методів, які він визначає, замість класів з яких він успадковується або модулів, у які він включений.
Шоб краще зрозуміти качину типізацію введемо наступні три класи - Duck, Goose і DuckRecording.

class Duck
def quack
'Quack!'
end
def swim
'Paddle paddle paddle...'
end
end

class Goose
def honk
'Honk!'
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) # => Quack!
puts make_it_quack(DuckRecording.new) # => Quack!

def make_it_swim(duck)
duck.swim
end

puts make_it_swim(Duck.new) # => Paddle paddle paddle...
puts make_it_swim(Goose.new) # => Splash splash splash...

Метод який вказує Качці (Duck) крякати, працює і для DuckRecording завдяки качиній типізації. Як і метод, який вказує Качці (Duck) плавати, буде працювати і для Гуски (Goose).

Використанні ресурси:
http://en.wikipedia.org/wiki/Duck_typing
http://rubylearning.com/satishtalim/duck_typing.html
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/100511

Немає коментарів: