Re: Packages and returning errors

From: Bigus (someone_at_somewhere.com)
Date: 11/27/03


Date: Thu, 27 Nov 2003 17:05:24 -0000


"Brian McCauley" <nobull@mail.com> wrote in message
news:u9k75mc7ly.fsf@wcl-l.bham.ac.uk...
> "Bigus" <someone@somewhere.com> writes:
>
> > I'm attempting to put together my first package, but there's something
> > pretty fundamental that I haven't sussed out:
> >
> > Say you are using the DBI module and you've just performed an query and
you
> > want to see if it returned any errors, you could do something like:
> >
> > if ( $db->errstr ) {print "That failed - ".$db->errstr;}
> >
> > What I don't get is what exactly is "errstr"? I guess it's a function
but
> > how would it work if I have a bit of code that goes:
> >
> > if ( $blah < $blahh ) {
> > $rtnError = "Below practical size";
> > return;
> > }
> > and I then want to test $instance->rtnError in the same way as DBI.
>
> The last error message is conceptually no different from any other bit
> of instance data. However you are storing the rest of your instance
> data, store the error the same way. Create an accesor...
>
> sub rtnError {
> my $self = shift;
> # Do whatever is needed to retrice the last error from $self
> # for example if this class is based on a blessed hash you could
> # say something like...
> $self->{last_error};
> }

I've just been reading the object-oriented tutorial
(http://www.perldoc.com/perl5.6/pod/perltoot.html) and looking through
various packages in my site/lib directory and it makes me realise how much
of Perl I really don't understand (or have difficulty grasping) and I've
been using it for 2 years :-(

Regarding the above rtnError sub, I don't understand what the "my $self =
shift;" line is for. The perldoc function guide says about shift (which is
not incidentally a function I've used before):

"Shifts the first value of the array off and returns it, shortening the
array by 1 and moving everything down. If there are no elements in the
array, returns the undefined value. If ARRAY is omitted, shifts the @_ array
within the lexical scope of subroutines and formats, and the @ARGV array at
file scopes or within the lexical scopes established by the eval '', BEGIN
{}, INIT {}, CHECK {}, and END {} constructs".

Errr, right.. it loses me at the "lexical scopes" point but the first bit
would seem to be the relevant bit in this case anyway. Since you are not
specifying anything after the shift keyword it would look for anything
contained in @_, which would be nothing if you were just calling the
rtnError method to return an error string to you defined elsewhere in the
module. So, what's the point of that line?

Another thing I don't get about shift is why one would want to use it
anyway. If an array of values are passed to a sub, shift will chop the first
one off as it returns it, which seems rather destructive, especially when
you could just as easily reference it with $_[0] and that would leave the @_
array intact.

The line "$self->{last_error}" - in terms of hashes, the dereferencer is
not something I've used before. I've used standard hashes like
"$self{last_error}", and hashes within hashes like
"$self{last_error}{blah}", but why is "$self->{last_error}" different than
"$self{last_error}"?

Back to my package (which I am currently thinking might be out of my depth,
and am considering going back to the idea of just writing a standard CGI
script instead!), I have the following code:

package GD::MyMod;
use strict;
use GD;

# new constructer expects 2 values passed
sub new {
    if ( $_[0] < 100 or $_[1] < 100 ) {
        my $error = "";
        $error = "Specify values >= 100";
        return;
    }
    else {
        # do stuff
    }
}

sub rtnError {
    return $error;
}
1;

Then, in the CGI script that calls it, I have:

#!c:\perl\bin\perl.exe
use GD::MyMod;
$im = new GD::MyMod(20,20);
print "Content-type:text/html\n\n";

if($im->rtnError) {
    print $im->rtnError;
}
else {
    print "no error";
}

That generates an Apache 500 server error and the erro log shows:

"Global symbol "$error" requires explicit package name at blah"

the line it refers to is the print "no error"; one. So, if I add the line
"my $error = shift;" before it (I don't know what it does, but the OO
tutorial uses it in it's subs) then I don't get a server error but a blank
page and the error log says:

Can't call method "rtnError" on an undefined value at blah, where blah is
the line if($im->rtnError) in my CGI script.

So, it seems that somethings not right with the new sub.. any ideas what?

Thanks
Bigus



Relevant Pages

  • Re: Packages and returning errors
    ... > array intact. ... sub is_a_instance_method { ... my $class = shift; ... You need to fix the scope of $error by moving its declaration outside ...
    (comp.lang.perl.misc)
  • Re: Replacing a line
    ... #Using core module Tie::File to process a file in this subroutine ... sub process_one_file { ... $cpp_file = shift; ... for (@array) #Each line should come one by one ...
    (comp.lang.perl.misc)
  • Re: ClamAV
    ... 'ABSTRACT' => 'A simple interface to the Clam Anti-Virus system', ... sub MY::test { ... package MY; ... my $self = shift; ...
    (comp.lang.perl.modules)
  • Re: any pointers please? combine words script
    ... ugly but i hate repeated code like that sub has. ... sf> my $source = shift; ... never name a temp, temp. ... sf> return @array; ...
    (comp.lang.perl.misc)
  • Re: Why isnt shift the same as $_[0]?
    ... use warnings; ... > sub AUTOLOAD ... Ahem, you are using shift as a hash key, not calling shift on @_: ... package My::Base; ...
    (comp.lang.perl.misc)