Duck Typing and Object Hashish

Been doing a little mail archive reading on Duck Typing, spurred on by Why!'s “What’s Shiny and New Ruby 1.8.0” http://whytheluckystiff.net/articles/2003/08/04/rubyOneEightOh . And, of course, i’ve also been using Yaml, a lot. And then there was something Why! mentioned about procs becomeing more like methods and … well, it got me thinking…

First, this Duck Typing thing. How well defined is it? I notice a post with:

[ed- Sorry if the identation gets lost, i’ll have to work on that]

def classify creature
match_methods (creature)
when(:quacks :wings) puts "duck"
when(:quacks) puts (“hunter”)
when(:wings :feather) puts "bird"
when(:wings :nocturnal) puts "probably bat or batman"
when(:wings) puts "airborne"
when(:legs) if creature.legs.count == 8 then puts “spider” else puts
"walking creature"
end
end

Thus we “type” an object by what it can do. An object’s class is then a sort of summary name for ALL it can do. yet this isn’t quite right either since objects can be dynamically extended. hmmm…so we really are left with just Duck Typing. Classes are merely a convient means of glue, sticking groups of methods together. The distinction between module and class seems almost strained.

but even more interesting. I’m sitting here looking at this yaml stream created from a ruby object:

— !ruby/object:SourceManager::Package
package: 'PackageName’
version: ‘1.0.0’

Obviously the corresponding class definition is something along the lines:

class Package
attr_accessor :package, :version
def initialize(package, version)
@package = package
@version = version
end
end

but if i strip off the !ruby/object:SourceManager::Package, the stream is transformed into a simple hash. So I wonder, could yaml know that the stream was a Package without being told, using only the magic of Duck Typing? Of course the answer is, not quite. Because their could be another class that responds to the very same methods. Which would be correct? But that’s interesting in itself b/c it means that it take but one unique accessable method to make a class distinguishable from any other:

class Package # but it dosen’t really matter what you call me, b/c
attr_accessor :i_am_a_package!
attr_accessor :package, :version
def initialize(package, version)
@package = package
@version = version
end
end

and yaml could “Duck Determine” the type of object the hash stream was. hmmm… so how distinct are hashes and objects really? bring in the idea of proc being like a method and…

Package = { :package => proc { @package }, :package= => { |x| @package = x },
:version => proc { @version }, :version= => { |x| @version = x },
:initialize => { |package, version|
@package = package
@version = version
}
}

Except for certain scoping issues, again, the distinction seems rather slight. At least for a duck. There’s probably already a name for this idea, but just the same I’ll call is Object Hashish.

Seems like a transition’s taking place…

My musings for the day…others thoughts/comments?

-t0

Hi,

Duck typing is essentially dynamic typing.

The main ethos for a large number of Ruby programmers (note that there
are also those that are
into static typing), is that you don’t worry about types. In Ruby an
object’s class is not its type,
unless you’re talking singleton class, in which case each object has its
own type (which isn’t useful).
So, rather than worrying about type, you just worry about the behavior
shown by the objects.

Note that this doesn’t mean you check for all the appropriate methods
and all that. Then you’re
going back to static typing. Just document that certain functions
require arguments to respond
to certain methods, and only call those methods with appropriate
arguments. And feel free to
unit test a lot to make sure everything responds as asked.

Basically, it’s design by contract without contracts being enforced with
code.

Hope this helps.

  • Dan

Well, that’s about as succinct as I’ve seen, and I appreciate it. It clears
up the concept quite a bit for me.

  • dan

“Dan Doel” djd15@po.cwru.edu wrote in message
news:3FB27522.1070501@po.cwru.edu…

···

Just document that certain functions
require arguments to respond
to certain methods, and only call those methods with appropriate
arguments. And feel free to
unit test a lot to make sure everything responds as asked.

Basically, it’s design by contract without contracts being enforced with
code.

Hope this helps.

  • Dan