Classes aren't types redux

Posted by Rick DeNatale Tue, 01 Aug 2006 18:55:02 GMT

Programming in a dynamically typed language is sometimes like casting roles in a movie or play. Even if the screenwriter wrote a part with a particular actor in mind, theneed often arises for an understudy or stand-in.

One of the mantras of Duck Typing is that “Classes aren’t types”. Another, more subtle, aspect is that even if it walks and talks, an object needs to be tried out for a role.

In the Pickaxe, Dave Thomas gives, as his first example of duck typing, the usefulnessof of using a String or an Array as a lightweight substitute for a File.

Stealing his example, he posits a class with a method which writes to the end of an open file:

   class Customer
      def initialize(first_name, last_name)
           @first_name = first_name
           @last_name = last_name
      end
      def append_name_to_file(file)
           file  << @first_name << " " << @last_name
      end
   end

He then goes on to show writing a test case for this method which instead of creating a temporary file to use as the parameter to the append_name method, uses the fact that both String and Array define << methods which do pretty much the same thing as the similarly named method in File. So even though the parameter is named file, the method really doesn’t care that it’s a File object, it really only cares that it responds to << by appending the argument to itself, and returns self.

   cust = Customer.new("Joe", "McGillicuddy")
   file_not = ""
   cust.append_name_to_file(file_not) 
      -> "Joe McGillicuddy"
   file_not 
      -> "Joe McGillicuddy"
   file_not2 = []
   cust.append_name_to_file(file_not2) -> ["Joe", " ", "McGillicuddy"]
   file_not2 -> ["Joe", " ", "McGillicuddy"]

So the file argument really doesn’t need to be an instance of File. Now let’s try a real file:

   real_file = File.open("file1")
      -> #<File:file1>
   cust.append_name_to_file(real_file)
      -> IOError: not opened for writing
             from (irb):7:in `write'
             from (irb):7:in `append_name_to_file'
             from (irb):20
             from :0

The point here, of course is that it’s not just the “type” which matters, it’s really if the object is able and prepared to do what is asked of it. Even though real_file is a file, this particular instance it’s up to the job. In one sense, it’s a duck, but it’s more of a duckling, able to walk and talk, but not fly!

Posted in  | no comments | no trackbacks

Comments

Trackbacks

Use the following link to trackback from your own site:
http://talklikeaduck.denhaven2.com/articles/trackback/5

Comments are disabled