Duck typing problem

Hello,

Suppose I have a class named Roelof.

Now I want to use ducktyping to test the class.

So I thought I could do :

def test(obj)
    obj.responds_to? (method)
end

but how do I do this when someone uses the test defenition like this

test(Roelof.new)

Roelof

Exactly the same. Roelof.new returns an object taht will be passed into your test method.

Note though that asking an object if it responds to a method isn't duck typing. Just call the method.

Henry

···

On 2/06/2014, at 5:20 pm, Roelof Wobben <r.wobben@home.nl> wrote:

Hello,

Suppose I have a class named Roelof.

Now I want to use ducktyping to test the class.

So I thought I could do :

def test(obj)
  obj.responds_to? (method)
end

but how do I do this when someone uses the test defenition like this

test(Roelof.new)

Henry Maddocks schreef op 2-6-2014 11:59:

···

On 2/06/2014, at 5:20 pm, Roelof Wobben <r.wobben@home.nl> wrote:

Hello,

Suppose I have a class named Roelof.

Now I want to use ducktyping to test the class.

So I thought I could do :

def test(obj)
   obj.responds_to? (method)
end

but how do I do this when someone uses the test defenition like this

test(Roelof.new)

Exactly the same. Roelof.new returns an object taht will be passed into your test method.

Note though that asking an object if it responds to a method isn't duck typing. Just call the method.

Henry

Thanks.

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.

Roelof

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:

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.

Eric MSP Veith schreef op 2-6-2014 14:32:

···

On Monday 02 June 2014 13:24:43, Roelof Wobben <r.wobben@home.nl> wrote:

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

Oke, I understand this,

But what I try is this.

Suppose you have the class A and you would check if it's a duck.
I think you can do class A.responds_to(:quack) and if that's true you know its a duck.

Roelof

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:

But what I try is this.

Suppose you have the class A and you would check if it's a duck.

Basically, you don't. It's the whole sense of duck typing: You do not longer
check, directly or indirectly, whether an object is of a certain class or
implements a certain interface. You just call obj.method().

I think you can do class A.responds_to(:quack) and if that's true you
know its a duck.

Again: You don't need to know. If it walks and quacks, for all what it's
worth, you can just assume it's a duck. It could be Cthulhu, but as long as He
walks and quacks, you just treat Him like a duck instead of going completely
insane.

      --- Eric

···

On Monday 02 June 2014 19:15:44, Roelof Wobben <r.wobben@home.nl> wrote:

Excellent answer. You helped me also a lot to understand this. :slight_smile:

···

On Monday, June 02, 2014 02:32:28 PM Eric MSP Veith wrote:

On Monday 02 June 2014 13:24:43, Roelof Wobben <r.wobben@home.nl> wrote:
> 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.

--

Regards,
Arup Rakshit

Debugging is twice as hard as writing the code in the first place. Therefore,
if you write the code as cleverly as possible, you are, by definition, not
smart enough to debug it.

--Brian Kernighan

Finally! A defence against the elder gods. Ia! Ia!

···

On Mon, Jun 2, 2014 at 12:55 PM, Eric MSP Veith <eveith@wwweb-library.net> wrote

Again: You don't need to know. If it walks and quacks, for all what it's
worth, you can just assume it's a duck. It could be Cthulhu, but as long
as He
walks and quacks, you just treat Him like a duck instead of going
completely
insane.

Eric MSP Veith schreef op 2-6-2014
19:55:

> > 
> > But what I try is this.
> > Suppose you have the class A and you would check if it's a duck.
> Basically, you don't. It's the whole sense of duck typing: You do not longer check, directly or indirectly, whether an object is of a certain class or implements a certain interface. You just call obj.method().
> > I think you can do class A.responds_to(:quack) and if that's true you
> > know its a duck.
> 
> 			Again: You don't need to know. If it walks and quacks, for all what it's worth, you can just assume it's a duck. It could be Cthulhu, but as long as He walks and quacks, you just treat Him like a duck instead of going completely insane.
> --- Eric
Oke,

Then I think I misunderstood the exercise.

The exercise is :

  You probably know, that in Javascript (and also Ruby) there is no

concept of interfaces. There is only a concept of inheritance, but
you can’t assume that a certain method or property exists, just
because it exists in the parent prototype / class. We want to find
out, whether a given object fulfils the requirements to implement
the “SantaClausable” interface . We need to implement a
method which checks for this interface.

Rules

  The SantaClausable interface is implemented, if all of the

following methods are defined on an object:

  • sayHoHoHo() / say_ho_ho_ho
  • distributeGifts() / distribute_gifts
  • goDownTheChimney() / go_down_the_chimney

Example

class SantaClaus
    def say_ho_ho_ho
        # Ho Ho Ho!
    end

    def distribute_gifts
        # Gifts for all!
    end

    def go_down_the_chimney
        # Whoosh!
    end
end

class NotSantaClaus
    def say_ho_ho_ho
    end
end

is_santa_clausable(SantaClaus.new) # must return TRUE
is_santa_clausable(NotSantaClaus.new)
# must return and the begin function looks like this : def is_santa_clausable(obj)
#TODO
end
Roelof
···

On Monday 02 June 2014 19:15:44, Roelof Wobben r.wobben@home.nl wrote:

I don't know where this exercise is from, but from this example it seems to
me that it's teaching terrible object design habits for dynamic languages.
With extremely rare exceptions (e.g. Ruby's internal conditional checks for
implicit conversion methods like #to_int), a program should have no need to
do this kind of "interface checking". If you want to write Java code write
it in Java and let the language take care of interface checks for you.

···

On Mon, Jun 2, 2014 at 2:15 PM, Roelof Wobben <r.wobben@home.nl> wrote:

Eric MSP Veith schreef op 2-6-2014 19:55:

On Monday 02 June 2014 19:15:44, Roelof Wobben <r.wobben@home.nl> <r.wobben@home.nl> wrote:

But what I try is this.

Suppose you have the class A and you would check if it's a duck.

Basically, you don't. It's the whole sense of duck typing: You do not longer
check, directly or indirectly, whether an object is of a certain class or
implements a certain interface. You just call obj.method().

I think you can do class A.responds_to(:quack) and if that's true you
know its a duck.

Again: You don't need to know. If it walks and quacks, for all what it's
worth, you can just assume it's a duck. It could be Cthulhu, but as long as He
walks and quacks, you just treat Him like a duck instead of going completely
insane.

      --- Eric

Oke,

Then I think I misunderstood the exercise.

The exercise is :

You probably know, that in Javascript (and also Ruby) there is no concept
of interfaces. There is only a concept of inheritance, but you can't assume
that a certain method or property exists, just because it exists in the
parent prototype / class. We want to find out, whether a given object
fulfils the requirements to implement the "SantaClausable" *interface*.
We need to implement a method which checks for this *interface*.
Rules

The SantaClausable interface is implemented, if all of the following
methods are defined on an object:

   - sayHoHoHo() / say_ho_ho_ho
   - distributeGifts() / distribute_gifts
   - goDownTheChimney() / go_down_the_chimney

Example

var santa = {
    sayHoHoHo: function() { console.log('Ho Ho Ho!') },
    distributeGifts: function() { console.log('Gifts for all!'); },
    goDownTheChimney: function() { console.log('*whoosh*'); }
};
var notSanta = {
    sayHoHoHo: function() { console.log('Oink Oink!') }
    // no distributeGifts() and no goDownTheChimney()
};

isSantaClausable(santa); // must return TRUE
isSantaClausable(notSanta); // must return FALSE

santa =
  sayHoHoHo: ->
    console.log "Ho Ho Ho!"

  distributeGifts: ->
    console.log "Gifts for all!"

  goDownTheChimney: ->
    console.log "*whoosh*"

notSanta = sayHoHoHo: ->
  console.log "Oink Oink!"
  # no distributeGifts() and no goDownTheChimney()

isSantaClausable santa # must return TRUE
isSantaClausable notSanta # must return FALSE

class SantaClaus
    def say_ho_ho_ho
        # Ho Ho Ho!
    end

    def distribute_gifts
        # Gifts for all!
    end

    def go_down_the_chimney
        # Whoosh!
    endend
class NotSantaClaus
    def say_ho_ho_ho
    endend

is_santa_clausable(SantaClaus.new) # must return TRUE
is_santa_clausable(NotSantaClaus.new) # must return

and the begin function looks like this :

def is_santa_clausable(obj)
  #TODO
end

Roelof

Hm, naw, I guess I misunderstood what you're trying to archieve.

Of course you can check explicitly whether some object "implements an
interface", although something like an interface doesn't _explicitly_ exist in
the Ruby world.

So, sure you can check whether a class would respond to a set of methods, like
you did with .respond_to? or by examinating the arrays returned by .methods or
.instance_methods.

Still, that seems to be alot like forcing a Java/C++ pattern on Ruby. Perhaps
somebody else can comment on this, but my guess would be that this is not the
way to Ruby Zen?

HTH.

      --- Eric

···

On Monday 02 June 2014 20:15:00, Roelof Wobben <r.wobben@home.nl> wrote:

Then I think I misunderstood the exercise.

Making a habit of checking type is indeed not the way to Ruby
Zen, but it is occasionally useful to write code that can take a
duck _or_ a zebra.

Imagine a method that will take either a Color object, or a
string or symbol with the color name:

     def scribble(color)
       color = Color.lookup(color) unless color.is_a?(Color)
       ...
     end

I imagine it is for purposes such as this that the tutorial
is teaching how to tell whether you've got a duck.

> So, sure you can check whether a class would respond to a set of methods, like
> you did with .respond_to? or by examinating the arrays returned by .methods or
> .instance_methods.
>
> Still, that seems to be alot like forcing a Java/C++ pattern on Ruby. Perhaps
> somebody else can comment on this, but my guess would be that this is not the

···

On 06/02/2014 12:14 PM, Eric MSP Veith wrote:
> way to Ruby Zen?

​A more Ruby way might be to have Color.lookup(color) be perfectly happy to
accept a Color object. Then you'd have:

  def scribble color
    color = Color.lookup color​
    ...
  end

​For comparison, see Kernel#Integer and friends.​

···

On 3 June 2014 06:17, Wayne Conrad <kf7qga@gmail.com> wrote:

Making a habit of checking type is indeed not the way to Ruby
Zen, but it is occasionally useful to write code that can take a
duck _or_ a zebra.

Imagine a method that will take either a Color object, or a
string or symbol with the color name:

    def scribble(color)
      color = Color.lookup(color) unless color.is_a?(Color)
      ...
    end

I imagine it is for purposes such as this that the tutorial
is teaching how to tell whether you've got a duck.

--
  Matthew Kerwin
  http://matthew.kerwin.net.au/

Matthew Kerwin schreef op 3-6-2014
2:10:

···
        On 3 June 2014 > 06:17, Wayne Conrad <kf7qga@gmail.com> wrote:
          Making a

habit of checking type is indeed not the way to Ruby

          Zen, but it is occasionally useful to write code that can

take a

          duck _or_ a zebra.



          Imagine a method that will take either a Color object, or

a

          string or symbol with the color name:



              def scribble(color)

                color = Color.lookup(color) unless

color.is_a?(Color)

                ...

              end



          I imagine it is for purposes such as this that the

tutorial

          is teaching how to tell whether you've got a duck.
        ​A more

Ruby way might be to have Color.lookup(color) be perfectly
happy to accept a Color object. Then you’d have:

        def

scribble color

color = Color.lookup color​

end

        ​For

comparison, see Kernel#Integer and friends.​


Matthew Kerwin

          [http://matthew.kerwin.net.au/](http://matthew.kerwin.net.au/)
thanks,

But what if someone does this

def scribble color.new

     color = Color.lookup ???

     ....

end

That's not valid Ruby code, I don't know what you're trying to represent
there. But this is what I was thinking:

  class Color
    @@names = {
      black: Color.new(0,0,0),
      white: Color.new(255,255,255),
    }
    def Color.lookup c
      case c
      when Color
        c
      when Symbol, String
        if @@names[c.to_sym]
          @@names[c.to_sym]
        else
          raise ArgumentError, "Not a color nane"
        end
      else
        raise ArgumentError, "can't convert #{c.class.name} into Color"
      end
    end
  end

  def scribble color
    color = Color.lookup color
    ...
  end

This is the opposite of duck-typing, it's effectively doing type casting.
If you call Color.lookup with a Color object, you get it back unmodified.
If you call it with no parameters, you get a generic Ruby "ArgumentError:
wrong number of arguments (0 for 1)" error.

···

On 3 June 2014 15:13, Roelof Wobben <r.wobben@home.nl> wrote:

Matthew Kerwin schreef op 3-6-2014 2:10:

​A more Ruby way might be to have Color.lookup(color) be perfectly happy
to accept a Color object. Then you'd have:

   def scribble color
     color = Color.lookup color​
    ...
  end

​For comparison, see Kernel#Integer and friends.​

thanks,
But what if someone does this

def scribble color.new
     color = Color.lookup ???
     ....
end

--
  Matthew Kerwin
  http://matthew.kerwin.net.au/

Matthew Kerwin schreef op 3-6-2014
7:44:

···
        On 3 June 2014 > 15:13, Roelof Wobben <r.wobben@home.nl> wrote:

Matthew Kerwin schreef op 3-6-2014 2:10:

A more Ruby way might be to have
Color.lookup(color) be perfectly happy to
accept a Color object. Then you’d have:

def scribble color

color = Color.lookup color​

end

For comparison, see Kernel#Integer and
friends.​

thanks,

            But what if someone does this



            def scribble color.new

                 color = Color.lookup ???

                 ....

            end
        That's

not valid Ruby code, I don’t know what you’re trying to
represent there. But this is what I was thinking:

class Color

@@names = {
                black:

Color.new(0,0,0),

                white:

Color.new(255,255,255),

}
              def

Color.lookup c

  case c
                when

Color

    c
                when

Symbol, String

                  if

@@names[c.to_sym]

@@names[c.to_sym]

    else
                    raise

ArgumentError, “Not a color nane”

    end
  else
                  raise

ArgumentError, “can’t convert #{c.class.name} into Color”

  end
end

end

            def scribble

color

              color =

Color.lookup color

...

end

        This is

the opposite of duck-typing, it’s effectively doing type
casting. If you call Color.lookup with a Color object, you
get it back unmodified. If you call it with no parameters,
you get a generic Ruby “ArgumentError: wrong number of
arguments (0 for 1)” error.


Matthew Kerwin

          [http://matthew.kerwin.net.au/](http://matthew.kerwin.net.au/)
Then Im confused by this test-case :

Test.assert_equals is_santa_clausable(SantaClaus.new), true

Roelof
    if @@names\[c\.to\_sym\]
      @@names\[c\.to\_sym\]
    else
      raise ArgumentError, &quot;Not a color nane&quot;
    end

The above can be written also -

@@names.fetch(c.to_sym, ArgumentError.new("Not a color nane"))

That seems to be a pretty elegant solution.

I'd remove the "Color.lookup" code in #scribble, however. IMHO, it introduces
alot of ambiguity: The user gets accustomed to methods that just take "a
sensible parameter", and in the end, comes up with some kind of parameter the
programmer hasn't thought of during API design.

(Disclaimer: I write C++ most of the time, and, by no means, have any
authority whatsover in Ruby API design. ;-))

What about:

---%<---
class Color
  def self.(sym)
    return self.lookup sym
  end
end
--->%---

That would allow easy access to the most commonly used color values and allow
the user to just call:

---%<---
scribble Color[:black]
--->%---

Sorry for hijacking this thread. I know it becomes quite philosphical this
way, but I'm very much interested in your opinions.

        --- Eric

···

On Tuesday 03 June 2014 15:44:13, Matthew Kerwin <matthew@kerwin.net.au> wrote:

That's not valid Ruby code, I don't know what you're trying to represent
there. But this is what I was thinking:

[...]

​Not quite, since #fetch doesn't​ raise the default. But you could use
either of the following:

    @@names.fetch(c.to_sym) {|k| raise ArgumentError, "Not a color name" }
    @@names[c.to_sym] or raise ArgumentError, "Not a color name"

​I wrote it my way first because, originally, I was going to start with `if
c =~ /#.../`, so the name lookup was the second if-statement, and it seemed
more natural to write it that way.​

···

On 3 June 2014 15:57, Arup Rakshit <aruprakshit@rocketmail.com> wrote:

        if @@names[c.to_sym]
          @@names[c.to_sym]
        else
          raise ArgumentError, "Not a color nane"
        end

The above can be written also -

@@names.fetch(c.to_sym, ArgumentError.new("Not a color nane"))

--
  Matthew Kerwin
  http://matthew.kerwin.net.au/