Re: Packages and returning errors

From: Matthew Braid (mb_at_uq.net.au.invalid)
Date: 11/28/03


Date: Fri, 28 Nov 2003 16:25:45 +1000

Bigus wrote:

> "Brian McCauley" <nobull@mail.com> wrote in message
> news:u9k75mc7ly.fsf@wcl-l.bham.ac.uk...
<snip>
>>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):

When you call a method like $object->method(arg1, arg2, arg3...),
method's @_ looks like ($object, arg1, arg2, arg3...). Likewise, if you
call SomeClass->method(arg1, arg2, arg3...), @_ looks like ('SomeClass',
arg1, arg2, arg3...).

So my '$self = shift;' basically just gets the object that the method
was called on (or the package).

> 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}"?

All objects are blessed _references_. This means $self is not a hash -
its a reference to a hash. You can't do $self{blah} because that makes
perl look for a hash called %self (which probably doesn't exist in this
scope). $self->{blah} means 'get the scalar value of the key blah from
the hash referenced to by the scalar named self'. Simply put, if you've
got an array, hash or code reference you need to use the -> to use it
like an array, hash or subroutine call (respectively).

> 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
> }
> }

This will not do what you expect - $_[0] will most likely be the string
'GD::MyMod'. See the shift stuff above. Plus $error needs to be shifted
out of the new sub and put in the package's scope if you want other
functions in the package to see it.

> sub rtnError {
> return $error;
> }

This does a little more than you probably expect. $error is a package
global (once you've made it one - at the moment its an unknown
variable), so its shared amongst all objects of type GD::MyMod (and is
even accessible directly from the class without instantiating an
object). I find error accessors like this useful, your mileage may vary.

> That generates an Apache 500 server error and the erro log shows:
>
> "Global symbol "$error" requires explicit package name at blah"

That's because you should have put

        my $error = "";

outside the sub new. At least you appear to be use'ing strict!

> 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:

Your new sub returned undef. GD::MyMod's new should have a 'bless' in it
to create the new object and return that object. perldoc -f bless.

MB



Relevant Pages

  • Module questions (perhaps a module creation mini-tutorial)
    ... sub new { ... I get a hash in $_with only one value - the string name of the ... package I am calling. ... Why does bless need an empty hash intialized for it to bless it? ...
    (perl.beginners)
  • Re: Inner classes, sort of?
    ... For reasons of encapsulation and object-purity and so forth, you don't want the caller to do that ... ... you'd have to make a separate package to define a class for the name/value hash. ... I'm wondering if there is some way to make the name/value hash a mini-class somehow, so that you could define accessor methods, without having to write a full-blown package that blesses the hash into a class. ... sub _listOfItems { ...
    (comp.lang.perl.misc)
  • Re: I sat, thought about this, and I still dont understand it.
    ... *$datum = sub { ... I'm still lost on how to insert data into the hash. ... package main; ... two new functions CData1 and CData2, and you can simply call them: ...
    (comp.lang.perl.misc)
  • Inheritence question
    ... I have a program where I create an class and pass a hash: ... sub new { ... Can some one give me a hint? ...
    (comp.lang.perl)
  • Re: looking for help with a counting algorithm
    ... >> subcategory is counted, the code goes back up the tree to the root, adding ... >> involve retrieving all the category memberships from the database, ... sub ReadCategories{ ... ReadCategories is called with two empty hash pointers by any of the ...
    (comp.lang.perl.misc)