On Jun 9, 2004, at 9:57 AM, Randal L. Schwartz wrote:

"Drieux" == Drieux <[EMAIL PROTECTED]> writes:

Drieux> if ( ref($got_back) eq "Foo::Bar")

No no no.  Stop using ref().  It means you can't replace it
with a subclass of it.

You want (and I show in my still-hidden article);

if (UNIVERSAL::isa($got_back, "Foo::Bar")) { ... }


On Jun 9, 2004, at 10:14 AM, Wiggins d Anconia wrote:
[..]

Example 2: Subroutine that returns a value or an exception on failure, must check type of return value

my $value = $obj->function_that_returns_value;
if (UNIVERSAL::isa($value, 'Exception')) {
    # rethrow exception
    return Exception->new->throw($value);
}
# optional else
else {
    # handle value here
}
[..]

the tactic I would probably use, besides wiggins,

        "clearly it is time to just refactor it all"

would be something on the order of

        my $exception;

        my $got_back = $obj->method(@args, \$exception);

since the 'list nature' of method invocation it would
be simpler in the initial pass NOT to change how things
are already being returned - so as not to break any of
the existing code. But I could start refactoring the
code slowly and transitionally.

hence in

        sub method {
                my ($var1,...,$exception) = @_;
                ...
                if (bad_condition)
                {
                        $$exception = new Foo::Bar
                                if ( ref($exception) );
                        ....
                }
                ....
        }

would be a part of the progression for that method,
it would not break any of the existing code.

This way leads to things like

        my $got_back = $obj->method(@args, \$exception);

        if ( $exception )
        {
                print "got exception\n";
                my $type = ref($exception);
                
                if ($type eq "Foo") {
                        print "doing foo type handling\n";
                } elsif ($type eq "Foo::Bar") {
                        print "doing foo::bar type handling\n";
                } else {
                        print "unknown exception - $type\n";
                }
        }

Which is where I have problems with the

        if (UNIVERSAL::isa($got_back, "Foo::Bar")) { ... }

approach is that problem of resolving who really
should be handling which 'classes' of problems anyway.

I will conceded that in the 'return value or exception'
the strategy is 'required' and more 'extensible' since we
would hope that Foo::Bar is a subclass of Foo.

Granted were one to 'sub class' "Exception" - then one
could start into the 'standard exception classes' - and
be off for a day at the races with the sorts of complications
that exist over in say java with their

        try {

        } catch {

        } catch {

        }
        ....

So one either adopts wiggin's generalized solution
as a last stage in the catching, and merely rethrows it,
or wouldn't it have been simpler to deal with it as

        if (UNIVERSAL::isa($value, 'Exception')) {
            # rethrow exception
           return Exception->new->throw($value);
        }

or why not simply go with

        if (UNIVERSAL::isa($value, 'Exception')) {
            # rethrow exception
           return($value);
        }

and let the caller deal with the crisis?

Allow me the argument the other way around, and a part
of the problem as I deal with it in c89 types of problems.

So I have library foo, it could throw an exception from
using something that sets errno, and could be 'stringified'
by perror(), so when foo_doo_bar(var,...) runs into that
problem rather than returning FOO_OK as the 'no errors noted'
return, it would return FOO_CHECK_ERRNO, and in the documentation
about the function it would note that if that were returned
then one would need to deal with the errno and if need be
use perror().

If the Library Bar were built on foo, it would know that if it
got FOO_CHECK_ERRNO, then it would know that it needed to deal
with what ever the errno was...

One part of the problem here is 'getting the exception handling'
into the process so that there are enough 'error message indicators'
to assert what went wrong, and hopefully where. But the b-side of
that would be working out how to deal with them.

The classic one that few have seen active is

        malloc failed

and the simplistic case of 'got malloc failure, exit' can
be ugly if one needed to embark upon an orderly shutdown
of the sockets, and other things.

Yes, all of this is implying a level of 'professional complexity'
that the typical 'new to scripting in perl' may not yet have had
the experience to know about or deal with. BUT... they did ask
us what sort of professional angst we have when out here.

HTH.

ciao
drieux

---


-- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] <http://learn.perl.org/> <http://learn.perl.org/first-response>




Reply via email to