You have a common problem. You had a small mistake, you
had a wrong idea about where the mistake was, came up with
a theory, and from there you have careened to a number
of erroneous conclusions. And now those conclusions leave
you unable to understand or accept good advice when you get
it.
ariels is right. You bless $Person::list into
no class at all. This blesses it into the empty class,
which is the root of the entire tree of package namespaces,
and is better known as main. This keeps you from calling
methods normally, so you get around this by directly
specifying the package to start the method search in. And
somehow you convinced yourself that the object didn't have
private data like the books says it should, so you started
using globals. (Probably you just wrote an accessor wrong
somewhere, and had a wrong conclusion.)
Please accept that everything you think you know is
probably wrong. It will make learning the
truth much easier. Here is some of that truth.
When a function receives a method call, @_ holds the callee
and then the arguments to the call. The callee is what the
method was called on, which can be a class (ie package name)
or an object (ie blessed reference). Normally only
constructors get package names, and they are supposed to
construct an object and bless them into that package. A
method call looks like $object->bar(@stuff)
(with the function getting an @_ that looks like
($object, @stuff)).
Now let's rewrite your code properly. First your module:
package Person;
use strict;
sub new
{
my $class = shift;
my $self = {};
return bless($self, $class);
}
sub name
{
my $self = shift;
$self->{NAME} = shift if @_;
return $self->{AGE};
}
sub age
{
my $self = shift;
$self->{AGE} = shift if @_;
return $self->{AGE};
}
sub exclaim
{
my $self = shift;
printf "I'm %s and i'm %d years old!\n",$self->{NAME},$self->{AGE}
+;
}
1; # Modules need to end in a true value
And the driver code.
#!/usr/bin/perl
use strict;
use Person;
my $foo = Person->new();
$foo->name("Stefan");
$foo->age(20);
my $bar = Person->new();
$bar->name("Barney");
$bar->age(3);
$bar->exclaim();
$foo->exclaim();
Yes, the constructor that you thought didn't work, does.
You typed it in wrong, blamed the wrong thing when strange
stuff started to happen, and went further and further
wrong from there. Points to take away.
- Be very hesitant to say that a well-regarded book is
wrong. It is more likely that it is right and you
merely misunderstood it. Try typing in exactly
what it has.
- When you get advice back on elementary topics, try it
before saying how it will or will not work.
- Before ever saying that things don't work like they
are supposed to work, look for elementary mistakes. Like
typos, or mixing code from 2 functions and getting a
result that does something unexpected. (Like bless an
object into the wrong package.)
- Use strict. It takes less work to use it than
explain why you didn't. :-)
| [reply] [d/l] [select] |
Sorry, typo. The method name should return the name, not
the age.
| [reply] |
I take all your points with the humility of a learner, but I must retort something you mistook my wordings. I never once said that book was wrong, I only stated that the code in the book was not working. There is a fine line betwixt the two, but i never really even meant to imply that the book was in any way wrong.Besides, please state the wrong assumptions that I made. If you expect to teach someone, you must define the wrong assumptions the student has made. And once more, I can read. The code you replace with mine is that of the Cookbook, from which the error was generated:
cannot find object "Person" in package main. I was forced in to main before I even made my wrong assumptions. I also tried very hard to copy code correctly and right any typos on the <bold>four</bold> different modules I tried. If you read this please respond but stating the assumptions I made and correcting them. Even if you flame me at least I can move on with my lessons
| [reply] [d/l] |
sub new
{
my $class = shift;
return bless({},shift);
}
which resulted in an error message like:
Can't locate object method "name" via package "main" at line 4.
Very confusing. So you you fiddled around with the code,
somehow decided that you needed to use a
global before eventually hitting on changing that line by
adding Person:: to the method name, which hid the
underlying problem. Your experiments probably were mostly
variations on the theme of telling it that you want,
"Person, not main you moron!" And by the time it
finally listened, you had what you posted.
BTW that was not meant as a flame. It describes a common
programming trap. Something
doesn't work like it is supposed to, blame is assigned
early, and the person goes into a pattern of somewhat
random experimentation until something (hopefully) works.
This is a natural tendancy but is horrible for
programming. You need to change one thing and only one
thing at a time. And random changes are probably bad
ones.
In this case, when you tried to type in examples from the
book and they didn't work, you should have looked closely
for how your code didn't match, and if you couldn't see it
then post showing your exact code, your error message, name
the book and page you are trying to copy, and say, "I don't
understand why this is giving me this error message, the
book says it should work?" Then someone would have told
you what your mistake was, and why your mistake resulted
in that error.
Just remember this for the future. If you find yourself
doing random things to get something to work,
you are trapped and need to back up, break down what is
happening into small logical pieces, take a break, or get
outside help. Random is bad. | [reply] [d/l] [select] |