Bigus said:
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.
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.
Using $_[0] and so on is ugly and slow.
The only time one usually does that is if one wants to modify
arguments.
The only time you usually need to worry about keeping @_ intact is if
you are going use a goto.
The "self" argument is logically separate from the rest of @_ so to
make this clear I tend to write:
sub not_a_method {
my ( $arg1, $arg2 ) = @_;
# Do stuff
}
sub is_a_instance_method {
my $self = shift;
my ($arg1, $arg2 ) = @_;
# Do stuff
}
sub is_as_class_method {
my $class = shift;
my ($arg1, $arg2 ) = @_;
# Do stuff
}
Some other people prefer to use either list assignment or shift to
unpack the whole of @_ in all cases. It's a style thing.
There are also some other people prefer to use subscripts to unpack
the whole of @_ in all cases. That too is a style thing, a _poor_
style thing!
The perldoc function guide says about shift (which is
not incidentally a function I've used before):
In 2 years! Wow!
"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.
Bzzt! It would be nothing if you were just calling the rtnError
_subroutine_ but if you are calling an instance method then $_[0] is
the object on which the method is being called.
Another thing I don't get about shift is why one would want to use it
anyway.
Go back at read the OO tutorial again. If there are bits you don't
understand feel free to come here and ask for help. Comming here and
asking for help without reading the tutorial first is a waste of
everyone's time. The answers you get here will probably be inferior
to the tutorial. And it there's anything unclear in the tutorial it
won't help it get fixed.
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}"?
Ah, before you read the OO tutorial you need to read the reference
tutorial. You've come here asking for some coaching with your running
and you've just admitted you've never walked.
Back to my package (which I am currently thinking might be out of my
depth,
You are. Way out of your depth.
and am considering going back to the idea of just writing a standard CGI
script instead!),
"Chalk and cheese". (Actually I hate that metaphor - cheese and chalk
are both roughly hologeneous solids. They have a lot in common. I
think "Chalk and chastisement" would be a better metaphor).
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 ) {
$_[0] will be 'CG::MyGod' if new is called as a method of class
GD::MyMod.
Did you perhaps "forget" to enable warnings?
I'm sure we've explained to you before how rude it is to come here and
ask sentient entities to help you when you've not already asked your
computer.
Are you _trying_ to piss us off?
Always use the natual representation of things. If you want to
represent the concept of "no value" in a scalar use the special value
undef. Rather helpfully when you declare a variable using my()
without an explicit initializtion it will be set to the natural
representation of "no value" for that type of variable.
$error = "Specify values >= 100";
return;
}
You are not saving that value anywhere that persists after the return
is executed.
Note your constructor does not construct anything if it gets an error.
You need to fix the scope of $error by moving its declaration outside
the subroutine.
I hope that some of that "stuff" includes actually constructing a
CG::MyGod object. Otherwise new() is not a constuctor.
}
}
sub rtnError {
return $error;
}
$error is out of scope.
Did you perhaps "forget" to enable strictures?
I'm sure we've explained to you before how rude it is to come here and
ask sentient entities to help you when you've not already asked your
computer.
Are you _trying_ to piss us off?
You need to fix the scope of $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);
It's probably bese not to get into the habit of using the indirect
ibject syntax. Oh, and you forgot to declare $im.
my $im = GD::MyMod->new(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"
You should not be runnning your scripts under a web server until
you've at least syntax checked them.
the line it refers to is the print "no error"; one.
No way! Look again.
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)
Don't just do random things. How did you expect $_[0] to contain your
error message?
then I don't get a server error but a blank page
I do not believe you.
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.
Yep that is correct.
So, it seems that somethings not right with the new sub.. any ideas what?
You decided that your constuctor would not constuct an object if it
didn't like it's arguments. If it didn't constuct an object you
cannot use the object it constucted to look up the error because there
is no object.
You need to call the rtnError as a class method, just as you did with
new.
Having a class method to return your error is just one approach.
There are other equally good ones.
--
\\ ( )
. _\\__[oo
.__/ \\ /\@
. l___\\
# ll l\\
###LL LL\\