"If you're OO, why are you exporting?"
I export the $errstr (and/or an alter-ego errstr() function) on demand. For no other reason than to give the user something to look for when new() fails. Maybe this is a sign I haven't properly thought through the OO creation/use.
I've been crawling the fence for some time on the OO issue.
Should I do so much in new() or should I simply create the object and make another method (say "connect") to do the rest of the work? Seems rather pointless to make 2 steps out of one. On the other hand, if someone were to use this in a long running script, they may want to get updates of the modem status. In which case the only option is to "new()" again, which doesn't quite seem right either. Or maybe the real answer is to break new into "new()" and "connect()" with a fall through from new -> connect.
Should I make a non-OO interface available? No reason why it can't swing both ways. The methods can be teased into using either the blessed object or a static variable. Especially if I break up new. | [reply] |
sub errstr {
my $self = shift;
return $self->{errstr} if Scalar::Util::blessed $self;
return $errstr;
}
That allows for the possibility of multiple objects.
As for new() failure, the meme is this:
my $obj = CLASS->new( ... ) or die CLASS->errstr;
My criteria for good software:
- Does it work?
- Can someone else come in, make a change, and be reasonably certain no bugs were introduced?
| [reply] [d/l] [select] |
Thanks!
That's exactly the kind of guidance I was hoping for.
| [reply] |
Should I do so much in new() or should I simply create the object and make another method (say "connect") to do the rest of the work?
A guideline that comes to mind here is isolate logic. Is an unconnected object useless? Is connection by necessity done with instantiation? Or in other words: does instantiation imply connection, and does connection imply instantiation. If the answer to any of those two questions is "no", then that's a hint that you should move the connection logic out of the constructor. (This shouldn't be confused with premature generalization, btw.)
Seems rather pointless to make 2 steps out of one.
This, of course, assumes that it indeed is one step.
if someone were to use this in a long running script, they may want to get updates of the modem status. In which case the only option is to "new()" again, which doesn't quite seem right either.
This seems to suggest that new and "connect" isn't one "logical unit" (a bit fuzzy, I know). If an unconnected object is useless, then you can still connect in the constructor.
Remember though that you don't have to solve everyones problems and requests. If you keep instantiation and connection bound, then a user of your class can create a delegator that has a reconnect method that creates a new object and thus only the delegator class needs to recreate the object and every copy of the end user object (the delegator instance) is updated with the new modem status.
Should I make a non-OO interface available? No reason why it can't swing both ways.
Is there any reason it should swing both ways? (This, I guess, is that dragonchild means by "... will be adressed by user requests" in his reply.) If you later want to have a procedural interface you can create a wrapper module for that. There's no need to have a dual interface. If you have a well-crafted class there shouldn't be any trouble for the user creating a new interface to it, and thus he doesn't have to bother you about it, nor wait for you to fix it (or apply the patch).
lodin
| [reply] [d/l] [select] |