More things worth stealing from Smalltalk

I've spent the day working on what has since become called Pixie, the object oriented database framework based around James's clever trick. Both I and the Fotango people have been working on 80/20 type solutions, but we appear to have different ideas about what constitutes the important 80%. So, I think I'll be merging tonight.

While I was beavering away on this, I finally got one of the classic OO commandments. This one's about constructors:

Your basic constructor, new should not take any arguments and should simply return an empty object

This seems somewhat counter intuitive; you're always going to set the attributes to something or other, or you're going to something else at instantiation time. Well, yes. And that's what factory methods are for. A new that takes an argument is an accident waiting to happen once you start doing the funky inheritance thing; you're going to have to remember what kind of mangling will go on elsewhere in the class hierarchy and your head is going to ache. 'Simple' constructors can also help with things like Class::MethodMaker's very lovely 'object' directive.

If you've got object invariants to worry about, don't. You can get 'round that by only calling the constructor via factory methods in the class (invariants should only be checked when flow of control leaves the object's methods after all).

If you combine this with Smalltalk type methods (which return $self unless there's a very good reason to return something else; even setter methods return $self) then you get to write nice code like the following:package Object;use Data::UUID;use Time::Piece;

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
Without JavaScript enabled, you might want to
use the classic discussion system instead. If you login, you can remember this preference.

Please Log In to Continue

Returning $self is something I'm very mixed on, but I think that's mostly because I do coding in such mixed environments - spending some of my time in C, and some in Perl. In C, the classic idiom of a setter is to return the old value. I'm not entirely sure that's worth it, as the use-cases seem to be few and far between. So I'm starting to use the return $self idiom far more often.

One module to note on this is SOAP::Lite, which does almost nothing BUT return $self on each call. And it seems to do pretty w

And, on closer inspection of the page source, spaces in the input have been replaced by '&nbsp; ', that extra space appears to be what's screwing things up. (Unless it's 'Plain old text' and <code> failing to get on)

I dunno. I will soon be adding ECODE (it is there now, but I need a few more fixes for it) which will allow you to seamlessly integrate blocks of code with regular text in plain text or HTML modes. Maybe tomorrow morning (I have some more testing to do with that and one other thing).

Factory methods do indeed return newly created and initialized instances (something you've gotten wrong in your example), but they also have the effect of deferred binding. The calling method is no longer explicitly naming a class. Rather, this detailed is hidden in the factory method, which is free to have either bind a class (package) name at compile time, or choose one at runtime. You'll see some of this in Smalltalk (at least in Objectworks and its successors) using a predecessor to the Strategy pattern

Bugger. I could have sworn I typed $class->new->set_foo($foo)
->set_bar($bar);

[fx: Hits 'edit' and fixes the code]

And I am aware of the late binding stuff. Perl makes that sort of thing so easy it's almost second nature now. In the Pixie::Proxy stuff I've been working on I have subclasses Pixie::Proxy::HASH, Pixie::Proxy::ARRAY etc. Pixie::Proxy::make_proxy($target, $store) looks at the target object to find out which subclass to instantiate, then does

The problem that I see with returning $self when you don't need to
return anything else is basically that the user's expectations of when
you need to do it, might not match yours. Does $wooz->save() return
$foo, or the success of saving it? Well, you run perldoc WoozleWuzzle,
and look up its "save" method, but by time you've done that, you
could've just written "$wooz->save; $wooz->print;" instead of bothering
to find out whether you could score style points by writing "$wooz->save->print;".