james_b wrote: > Sean O'Dell wrote: > >> The method print doesn't seem to me to belong, logically, to the >> string "Hello world", so I don't expect the string to know how to >> print itself. It does seem to me to belong as a method of $stdout, >> however. > > There's a series of articles [0] by Alan Holub about writng UI, based on > the idea that an object should know how to render itself. In it, Holub > claims, > [quote] > I'll explain the whys and wherefors in a moment, but here are some rules > of thumb that you can apply to see if you're really looking at an > object-oriented system: This is, to me, quite insane. =) That puts too much on the shoulders on the object developer. This assumes that "UI representation" is a natural function of the object, which it is not. That's a subjective parameter that Alan Holub wanted, and completely ignores what others may want from the object, and that, in my opinion, is the *epitome* of breaking object-orientation. =) > * All data is private. Period. (This rule applies to all implementation > details, not just the data.) I believe I disagree. Dangerous details should be private, yes. But sometimes data can be exposed when it is protected, because often, a class variable is itself an object of another class and has its own protections. If he means raw data, dangerously exposed data, then I agree. > * get and set functions are evil. (They're just elaborate ways to make > the data public.) They're ugly, but if you want to expose potentially dangerous data elements safely, you have to have these methods, albeit in a more coder-friendly form (obj.var and obj.var=). Unless he means actual functions named "get" and "set" for class member variables. Those do creep me out. Member variable access should be virtualized somehow. > * Never ask an object for the information you need to do something; > rather, ask the object that has the information to do the work for you. This is one of those things I was talking about earlier that I also thought was ludicrous. In a system like this, no object can use the information from any other object. It's expected to stand-alone and perform in a vacuum. Silliness I say, silliness! > * It must be possible to make any change to the way an object is > implemented, no matter how significant that change may be, by modifying > the single class that defines that object. Well, this turns right around and shows some open-minded thinking, if I read this right. This sounds somewhat Ruby-esque to me. Every object should be completely modifiable at run-time. Not sure if I agree with the "by modifying the single class that defines it" part though. >> I remember back in the early 90's when I first dove into C++, there >> seemed to be this thought process regarding OOP that went something >> like: every object should be able to stand alone and interact rarely, >> if ever, with anything else because that would break the object's >> encapsulation. I got that feeling from several texts, and I thought >> it ludicrous at the time, and still do. As things have evolved, it >> seems common sense has stepped in to replace those purist theories, >> but that article really took me back to that time. > > It's true there are countless possible messages one could send to a > String object, so having String know about all of them in advance is too > much. (There's been a similar discussion on ruby-talk regarding math > functions) I like the Math function organization. I see a fair blend of logic and practicality in the way they were laid out. > And while the convention in many langauges has been to pass a String > object to an IO object, it may be more appropriate to do it the other > way around, and just call String.print or String.print( someIoObject ) > > Luckily, it's dead simple to add this to your code by enhancing the > String class. > > class String > def print( io=$stdout ) > io.puts( self ) > end > end > > I've been doing this sort of thing in my code, and after a while it > struck me as common sense, not purist theory. I find it goes a long > way towards cleaning up or avoiding procedural code where I want OO, and > I find it easier to read. It strikes me as purist theory. I tried a lot of this sort of thing, too and found it was sdrawkcab. What you have there is a string class that knows how to print itself to any object which supports a "puts" method. But puts might not be the right paradigm for other objects that the string could be printed to, such as a socket or a streaming compression object. You then either have to switch back to letting the other objects print with the string, and now you have this mixed code (sometimes the string prints itself, sometimes other objects handle the work) or you have to add more method to the string object. That's ugly to me. Perhaps not to others, but it is to me. > As Holub states, "I should say that although the foregoing attitude > might sound extreme, my ideas don't stem from some academic notion of > purity; rather, every time I've strayed from the straight and narrow in > my own work, I've found myself back in the code fixing it a month or two > later. All of this do-it-wrong-then-go-back-and-fix-it work just started > taking up too much time. It turned out to be easier to just do it right > to begin with. My notions, then, are based on practical experience > gathered while putting together working systems, and a desire to put > those systems together as quickly as possible." > > That's pretty much how it's worked for me. None of the above really strikes me as purist, it strikes me as wishful. I think Ruby right now is pretty close to the purity I have, over my 12 years of OO-coding, come to believe is how OO should work. Actually, Ruby has taught a lot of new things; not the least of which is run-time morphism. I guess I can explain how I see OOP something like this: the real world is made up of objects. You can describe OO programming in terms of real-world examples. I am an object. I am made of other objects. I interact with other objects. But I move through the world, and do everything I do, procedurally. I am an object which moves through life procedurally. I have my job, other objects have theirs. Our places in the world are clearly defined by "what I am" and "what I do." So, in my line of thinking: me.eat(food) "Hello world".print to me equates to: food.eat. I eat. Food doesn't eat. $stdout prints. Strings don't print. Again, this is all just my opinion. I hope I didn't come across as insulting; if I did, I apologize in advance! Sean O'Dell