Beefy Boxes and Bandwidth Generously Provided by pair Networks Cowboy Neal with Hat
Perl Monk, Perl Meditation
 
PerlMonks  

Re: Classes Are Killing Me

by ariels (Curate)
on May 19, 2002 at 06:27 UTC ( #167618=note: print w/ replies, xml ) Need Help??


in reply to Classes Are Killing Me

Always turn on warnings (<samp>perl -w</samp> or <samp>use warnings</samp> in newer Perls); for that matter, use strict unless you have good reason not to. In your case, -w would have caught the bug in your constructor:

sub new { my $class = shift; return bless($Person::list,shift); }
doesn't use $class, instead preferring to shift some other element off of @_ to use as the class name. Additionally, you're always blessing and returning the same object (needlessly stored in a global variable), which is probably not what you wanted to do. In your case, you're passing undef to bless; you want to say
sub new { my $class = shift; return bless({},$class); }
Continuing down your code, your methods aren't reading the object they should be working on. You want to say e.g.
sub name { my $self = shift; $self->{NAME} = shift; }
Do this, and you should be able to say e.g.
my $person = new Person; $person->name('Me');

I'm curious, though, why you say ``the code in "Perl Cookbook" didn't work''. Could you please point us to what isn't working there?


Comment on Re: Classes Are Killing Me
Select or Download Code
Re: Re: Classes Are Killing Me
by straywalrus (Friar) on May 19, 2002 at 12:50 UTC
    I covered the fact that I was only able to create one instance of this class without losing data associated with it in my first comment to Chromatic(the comment is two above yours). However thank you for reiterating such a point. The code in perl cookbook would not even create an object or (after modification) it would not find the functions in package main.Of course this was shifting off of $class and even then they would not find the functions. If you really want the error returns, I could retype those programs and start a fresh to generate the errors. And in fact, the second most simple constructor is bless({},shift); I ussually use strict but i did not here, but if you noticed i made it very simple to add use strict: most variables are preceded by my. And this was just an example that I was trying to get to work. If i really wanted to I could (and do for my other projects) use strict
      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.
      1. 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.
      2. When you get advice back on elementary topics, try it before saying how it will or will not work.
      3. 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.)
      4. Use strict. It takes less work to use it than explain why you didn't. :-)
        Sorry, typo. The method name should return the name, not the age.
        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

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://167618]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others perusing the Monastery: (6)
As of 2014-04-17 03:53 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    April first is:







    Results (439 votes), past polls