From: James O'Brien Date: 2010-07-18T19:46:48+09:00 Subject: Re: ruby abstraction --0016e65b5f1812f420048ba72be7 Content-Type: text/plain; charset=ISO-8859-1 David, many thanks! i found your explanation very useful.. and an article on duck typing is well worth reading e.g http://en.wikipedia.org/wiki/Duck_typing for any other ruby newbies out there! n Sun, Jul 18, 2010 at 5:53 AM, David Masover wrote: > On Saturday, July 17, 2010 08:21:10 pm James O'Brien wrote: > > I have found the concept of an interface invaluable in my Java > programming > > and wondered if there were an equivalent concept in Ruby? > > Yes and no. > > Yes, there is certainly a concept of an "interface" -- this is an abstract > concept that really applies to all languages. But no, it's not built-in to > the > language. > > More specifically, the Java concept of an interface is only really needed > because Java is statically typed. > > > as a thought-experiment I > > propose Java without interfaces would be worse > > Probably. > > Take some common examples from the Java standard library -- Map would be a > good one. Now, Interfaces are especially cool because I don't have to care > that an object actually uses a hash internally -- it might use btrees, it > might use something entirely different -- all I care about is that it > claims > to behave roughly like a Map is supposed to, and it presents get(), put(), > and > so on. > > So, for example, I could declare an object to have a type like this: > > Map> files; > > You could conceivably store these files as a HashMap, mapping filenames to > lists of lines in the file. Of course, the cool part about interfaces is > that > it could also be a thin wrapper around a real filesystem (so you don't have > to > slurp them all at once), or it could talk to a database, or any number of > things. > > But on closer examination, was that actually the right abstraction? What > are > you doing with those files that you care that they're lists of strings, and > not one giant string or an IO stream of some sort? > > In the statically-typed world of Java, it makes sense that you would define > your interfaces up front like this, because everything needs to have a > type, > and types are all defined and planned out ahead of time. It's not just that > it'd be horrible design to do this: > > Object files; > > It's that it wouldn't work -- in order to call any methods on it, you still > need to typecast it to something you know how to interact with. > > In Ruby, things are a bit different. We have this concept called "duck > typing" > -- if it quacks like a duck, it may as well be a duck, who cares what it > actually is? If it isn't a duck, it should break our unit tests, which is I > think where it ties in to your comments here: > > > I'm well versed in > > the benefits of test driven code and documentation but we have this in > Java > > too > > Since Ruby is dynamically-typed (and duck-typed), I don't specify the > interface I need -- at least, not directly. I specify it by how I actually > use > the object in question: > > puts files['readme.txt'] > > Now, there's still an implicit interface -- in this case, "Something that > responds to [], and returns something which puts knows how to turn into a > string." But I don't have to spell that out in code -- again, either it > works > (which it does, 99% of the time) or it causes a runtime issue, which is > what > unit tests are for. > > That's the crucial difference -- in Ruby, I can just blindly fire a method > call on an object, without knowing what type it is. In Java, I can only > call > methods on the object when I know it's of a type that supports those > methods, > and which type it is. > > So, in Java, interfaces actually let you do things you wouldn't otherwise > be > able to do. In Ruby, I don't really see what purpose interfaces would have, > or > what they would enable me to do. I much prefer the implicit duck-typing > interfaces. If it's a situation where I need an explicit interface as > documentation, I think documentation works well enough. > --0016e65b5f1812f420048ba72be7--