This is a good explanation of duck typing. If you are still having trouble with it you might consider picking up a copy of: "Practical Object-Oriented Design in Ruby“ By: Sandi Metz
Very good book easy to follow and excellent chapter on duck typing among other handy features of object oriented design.
Can anyone then give me a hint how to solve this by duck typing ?
I have read many pages about it but I still confuses me.
With "traditional" object-oriented programming, a class is also a data type. That meant: different class, different data type. If classes have the same ancestor or implement the same interface, they can be casted to that base class or interface. Basically, the common denominator. Whenever the method you want to call is defined in that base class/interface, you can call it, not matter what actual class you have.
Now, introduce duck typing. Duck typing has the popular slogan "If it walks like a duck, and quacks like a duck, I'll happily treat it as a duck." That means that there is no need for common base classes or interfaces any more. If classes A and B share the same method signature, you can call it on both classes, no matter what they otherwise do.
Consider, for example, two classes: A PDF writer and a network socket. Suppose they both have the method "write(something)" defined. Now, the two classes do not share anything else. They have no common ancestor and implement no common interface. In fact, they perform two completely different tasks!
Somewhere in your program, you want to serialize a text. You call "writer_object.write(my_text)". But there are different code paths that lead to this certain point, and in one case, you may end up with a PDF writer object stored in the variable "writer_object", and in anthoer case, it may be the socket.
In ruby, this works. The results are different, of course, but it works. The vast advantage is that you can decide on your program's behaviour somewhere in your code, but have the very same method writing the text.
For example, there could be a user interface where the user could select "Send Text via E-Mail" or "Print Text to PDF". Based on that selection, your code would instanciate either the Socket class or the PDF writer. However, the other part of your code that is responsible for serializing it does not have to know about this choice, it just happily uses the "write" method.
A small code example of Duck Typing in action could look like this:
---%<---
[1] pry(main)> class A
[1] pry(main)* def quack()
[1] pry(main)* puts "Quaaa!"
[1] pry(main)* end [1] pry(main)* end => nil
[2] pry(main)> class B
[2] pry(main)* def quack()
[2] pry(main)* puts "Quack! Quack!"
[2] pry(main)* end [2] pry(main)* end => nil
[3] pry(main)> def do_quack(a_class)
[3] pry(main)* a_class.quack()
[3] pry(main)* end => nil
[4] pry(main)> do_quack(A.new)
Quaaa!
=> nil
[5] pry(main)> do_quack(B.new)
Quack! Quack!
=> nil
--->%---
As you can see, the "do_quack" method does not care whether its an instance of class A or class B it gets passed, it just calls the "quack" method. And in fact, it yields different results each time.
HTH.
--- Eric
···
On Monday 02 June 2014 13:24:43, Roelof Wobben <r.wobben@home.nl> wrote: