package Foo::Live;
sub new {
my $class = shift;
return bless {
iterator => Iterator->new(class => $class)->where(live => 1);
}, class;
};
sub next {
my $self = shift;
$self->{iterator}->next;
};
is particularly bizarre (if you accept the chained method idiom). Yet I wouldn't expect:
my $foo = Foo::Live->new;
while (my $subfoo = $foo->next) { print "$subfoo\n" };
to fail silently if where returned an error object. These are the sort of, I think, legitimate uses that could cause unexpected results. YMMV
This part of the design is only for methods that don't return interesting values, merely success/failure notification (though in the form of an object to enable chaining of methods). So if you are in the habit of squirreling away uninteresting values in long-lived locations that you never check, then, yes, you won't know about failures until global destruction.
When I use the method-chaining idiom I am often interested in the last value. Perhaps this is an argument against method chaining ;-)
But then, if you do that and don't have my error object, then you won't know about failures period, so I fail to see the problem.
Depends. In the cases where you are using method chaining you get an error as soon as you try and treat it as an object.
Yes, if I always threw exceptions you could argue that one would know about failures no matter what,
You knew what I was going to say didn't you :-)
but I think you'd find many people would just get very sloppy about catching and ignoring way too many exceptions and you really wouldn't be in that much of a better position.
I guess part of it is that I like to have a uniform error handling mechanism across a project. My mental facilities are too meagre to spend time considering whether a normal return value, an error object or an exception is more appropriate. So I just throw an exception. In my personal experience this helps more than it hinders.
I can see some value in "all failures are exceptions", but I really do think it goes too far. Sometimes the failure cases are the reason for the flow and so should be handled as part of the flow, not forced into some exception catcher. Why just this week I was forced to catch some exceptions that really should have been normal failures and it was much more painful that way.
I just never find it that much hassle. I still code so that success is indiciated by a true return value. That way you can always write:
$o->foo unless eval { $foo->bar };
avoiding nasties like
eval { $foo->bar };
$o->foo if $@;
When the exception is the driver for the mainline.
Anyway - I think this is probably a to-may-to/to-mah-to issue so I'll shutup and stop being annoying :-) |