4 Posts Tagged 'OOP' RSS

CLOS vs. Ruby

I thought I sort of understood CLOS, until...

CL-USER> (defclass foo ()
       ((bar :initform "BAR" :accessor bar)))

#<STANDARD-CLASS FOO>
CL-USER> (defparameter *x* (make-instance 'foo))
*X*
CL-USER> (bar *x*)
"BAR"
CL-USER> (defclass foo ()
       ((bar :initform "NEWBAR" :accessor bar)
        (baz :initform "BAZ" :accessor baz)))
#<STANDARD-CLASS FOO>
CL-USER> (defparameter *y* (make-instance 'foo))
*Y*
CL-USER> (bar *y*)
"NEWBAR"
CL-USER> (bar *x*)
"BAR"
CL-USER> (baz *y*)
"BAZ"
CL-USER> (baz *x*)
"BAZ"

The last line was unexpected.

Note in Ruby:

#!/usr/bin/ruby

class Foo
  attr_reader :bar
  def initialize
    @bar = 'BAR'
  end
end

p x.bar # => "BAR"

class Foo
  attr_reader :baz
  def initialize
    @bar = 'NEWBAR'
    @baz = 'BAZ'
  end
end

y = Foo.new

p y.bar # => "NEWBAR"
p x.bar # => "BAR"

p y.baz # => "BAZ"
p x.baz # => nil

So redefining a class alters objects that were already instantiated using an older version of the class. I'm not sure how that works.

December 20, 2007 @ 11:59 PM PST
Cateogory: Programming
Tags: Ruby, Lisp, OOP

PHP namespaces? Nope!

Today, I found out that PHP 5 still doesn't support namespaces. This is kind of extremely crap. I wrote a bunch of classes whose names are simple things like Scale and Numeric. These are good names because non-programmers have to work with this code, and certain names have meanings in those people's field of study which would be helpful to re-use for their sake.

But now I have to rename my classes because I'm sure they're going to clash with something, having such simple and generic names. So I'm likely going to have to append a string to the front or end of each one, e.g. ScaleQuestion and NumericQuestion.

In other words, now I get to implement a hacked-up version of namespaces myself, in nice slow PHP code rather than native compiled PHP-interpreter code, using manual string manipulation of class names. The only thing that's going to allow me to do this is the fact that PHP lets you use strings as symbolic references, which itself is incredibly evil.

Which is worse, living with a deficiency of the language and dumbing down / un-abstracting my code, or making up for its deficiencies by essentially constructing and eval'ing a bunch of strings?

November 13, 2007 @ 1:53 AM PST
Cateogory: Programming
Tags: PHP, OOP

Javascript forays, PHP adventures

To add yet another language to the ever-expanding list of languages I know well enough to get by but have far from mastered, in the past week or two at work I've needed to play with Javascript a lot. I've long thought of Javascript as the bane of my existence, if only for the horrid browser incompatibilities you have to deal with. I hate hate hate hate writing code that needs to have a bunch of silly conditionals that change the code's behavior based on differences in the underlying platform. In this case of course the platform is a browser, but I hate it equally dealing with differences between operating systems, differences between versions of libraries, and other similar things.

The ideal situation is to use some library where someone has already worked out those platform-dependent quirks. In the case of Javascript, there's JQuery. It really does work wonders. I read recently that Google uses it for some of their sites, and I can probably see why. JQuery gives you some helper functions that let you deal very nicely with event handling and element-selection.

To my surprise, Javascript actually is turning out to be a surprisingly powerful language. It apparently supports closures, and functions are first-order objects. The OOP system in Javascript is oddly different from other languages I've used, but it's workable. I'm doing some relatively funky stuff, and Javascript is handling it well enough. And everything I've done in JQuery so far works in IE6 and Firefox. That's a good sign.

In the course of all this, I'm also using PHP. I had to repress a PHP-induced shudder even as I write this. But this is my first venture into the realm of PHP5, and again it's turning out OK. They made a lot of changes between PHP4 and PHP5, many of which made a difference. The language is still far too verbose for my tastes; Ruby has spoiled me in terms of variable names without the need for Perl-style sigils. And the overload of array()'s in PHP still drives me batty. But this time, I'm making heavy use of some third-party libraries, e.g. Smarty templates for my interface, and Spyc to read some YAML for config and input files. It lets me do stuff in PHP without actually writing much code in PHP. Can't beat that.

Maybe that's the secret of life: to make up for deficiencies in languages I dislike by using tons of third-party libraries. Maybe. Well, no, probably not.

In other non-news, my Gentoo box should arrive at my door via UPS on Thursday. Sweet sweet salvation. I'm going to put this Vista laptop in the closet and bolt the door shut.

November 07, 2007 @ 12:39 AM PST
Cateogory: Programming

Design Patterns continued

I'm about halfway through Design Patterns: Elements of Reusable Object-Oriented Software, and it's pretty good. I can't read Smalltalk very well, so that's an impediment, but most of the code is C++ so it's OK. The book itself is very well-written. The patterns are laid out in a clear and thorough format, explaining pros and cons, giving good examples of when to use each pattern and when not to. The patterns are grouped by what purpose they're trying to serve, and similar patterns are compared / contrasted. The book sounds almost like it's trying to prove to the world that design patterns really are practical and relevant, which is amusing in hindsight because they obviously succeeded in doing so, at least among some large portion of programmers today. The "Lexi" example program used to introduce patterns in the first third of the book is pretty dated at this point, based on what looks like Motif and Windows 3.1 widgets etc., which isn't surprising given that this book is from 1994.? But the catalogs that come after are still very relevant and a joy to read.

I've been struggling with something in a Rails app I've been working on. It has to do with how to organize a hierarchy of parallel "model" classes. I had a sort of Eureka moment reading Design Patterns, when I realized one of the patterns is exactly what I need to solve this problem. That's always good. My original solution was a horrendous hack involving runtime editing of classes to inject methods into them, and it was entirely broken when pushed beyond a certain point.

For some reason I tend to overlook inheritance as a "decision-making" tool.? Saying "I'll take any object that implements this interface" or "I'll take any object of this class or its subclasses" is a nice open-ended yet well-structured way of implementing a conditional.? "When you give me an object, if the object meets these criteria (by nature of being of a certain type or implementing a certain interface), proceed, else fail immediately."? You let the compiler or interpreter do the work for you.? And if the object meets the criteria, you can use it while blindly assuming it'll work as expected.? I'm always muddling up my code and trying to juggle a million things at once and doing other classes' work for them in all the wrong places, instead of letting classes properly handle their own business independently.? I definitely have some bad programming habits that I'm trying to unlearn, with some success I think.? If nothing else, I have experience doing things the wrong way and clearly seeing how and why they're wrong and the price of being wrong, so hopefully in the future I can avoid the same mistakes.

So, the book is largely about design decisions.? Not just breaking a problem up into parts, but breaking them up into parts with the right granularity, and with the right relationship to other parts, and with the ability to be easily used in the future to solve other problems.? That's the hard part of programming, I guess: making those design decisions.? For me anyways, at this point.? The book is helpful in that regard.

It's interesting how so many of these patterns have little or no relevance to Ruby. For example, the Abstract Factory pattern. The book uses Smalltalk as an example of a language with classes that are themselves objects like any other objects; a language with class objects can just use the class objects themselves as factories. As the book says, a class object is already a factory: a factory that produces objects of a single sort. And produces them very nicely, for that matter.? But other patterns do apply to Ruby. Obviously it also depends somewhat on the specific problem you're trying to solve, but it's fun to try to think of which patterns might be more relevant than others given how different a language like Ruby is from a C++ or Java or what have you.

August 14, 2007 @ 9:49 PM PDT
Cateogory: Book Reviews