From: Francis Hwang Date: 2004-11-12T00:40:33+09:00 Subject: Re: Thinking About Java Interfaces In Ruby On Nov 11, 2004, at 10:19 AM, James Edward Gray II wrote: > > Does Ruby combat The Fragile Base Class Problem with philosophy alone? > I'm referring to Duck Typing here, of course. Let them pass in what > they want and if it responds to all the right messages, we don't care > what it is. In this scenario, we're not supposed to check "kind_of?" > at all, right? In that case, how do you document a method like this? > > class DatabaseTable > # ... > > def export( exporter ) > exporter.start_table > exporter.store_metadata(@name, @width, @column_names) > @rows.each { |row| exporter.store_row(row) } > exporter.end_table > end > end > > You don't really just say, "Pass in an object that responds to X, Y, > and Z." in the RDoc, do you? > In the RDoc, you usually say "Pass in an object of X class." RDoc comments ideally are a sort of loose contract, so when you say that you're implying "You can poke around with other classes, but there's no guarantee this library won't blow up when you do it, and there's no guarantee the internals won't change in the future so that a hack that works today will break tomorrow." It's a philosophical difference, and it's fairly profound. Heavy OO theory seems to believe more or less in Platonic ideals: There are universal types that exist in the universe, and if you do a lot of domain research up front you'll discover them all and won't have to refactor much as you implement. (This is comparable, incidentally, to Islamic illustrators of antiquity, who were not allowed to make drawings that mimicked nature, so every time they drew, say, a horse, they would say they weren't drawing a particular horse in the world, but the essence of all horses.) Lightweight OO theory -- expressed in the idioms of Ruby and other light OO languages like Smalltalk -- says that types are provisional, and to a certain extent, they're just convenient lies we tell ourselves to get our work done. (If you want, you can tie this into certain strains of Buddhism which argue that the self is an illusion we hold up to get through the day.) You define your classes as you need them, but the time may come when you discover that the class needs to be redefined or discarded entirely, so you do what is necessary for the moment and move on. Note that most of this is untenable without rigorous unit testing. And in fact, the recent popularity of Ruby and *cough* Python owe more than a little to the bubble in XP and Agile methodologies a few years back. People started unit-testing in Java, then they realized that once they were writing the tests, all that static typing caused more harm then good. On a level of expressiveness, I think one of the nice consequences of unit testing is the fact that you can encode a lot of subtle assumptions into those tests. As opposed to trying to write a class and interface, that's not going to encode nearly as much. F.