Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?

Re^3: Perl class - how to create instance variable instead of class variable

by TGI (Parson)
on Dec 20, 2010 at 00:36 UTC ( #877955=note: print w/replies, xml ) Need Help??

in reply to Re^2: Perl class - how to create instance variable instead of class variable
in thread Perl class - how to create instance variable instead of class variable

It looks like you didn't read the advice anyone posted here, or at least didn't understand it. I'll make another effort in the hopes that you will actually read it and work at understanding.

I've gone through the entire process of trying the advice to use the strict pragma, understanding the error message, and checking the docs for help. I've tried to follow an approach that would make sense for a novice perl programmer who does not have all the syntax and rules memorized.

First we try running the code like this:

package Test; use strict; use warnings; sub new { my $class = shift; my $self = {}; bless $self, $class; return $self; } sub getValue { my $self = shift; print "\n~~~~~~~~getValue :$self \n"; $self{theValue}; } sub setValue { my $self = shift; my $value = shift; print "\n~~~~~~~~~~~set value: $self \n"; $self{theValue} = $value; } 1;

What do we get?

Global symbol "%self" requires explicit package name at line 1 +5. Global symbol "%self" requires explicit package name at line 2 +2.

We can run splain on these errors to get a more detailed error message. The result is:

(F) You've said "use strict" or "use strict vars", which indicates + that all variables must either be lexically scoped (using "my" or +"state"), declared beforehand using "our", or explicitly qualified to say which package the global variable is in (using "::").

Lines 15 and 22 are where we attempt to access the values in $self with syntax like $self{theValue}. Yet for some reason, perl thinks we are trying to access %self and not $self. Why?

Let's start by asking what each code construct means.

  • %self is a hash called 'self'. It doesn't exist, but perl says we am asking for it on line 15 and 22.
  • $self is a scalar called 'self'. In each of the subs involved in the error message, it is the first variable in the argument list. Since I am using these subs as methods the first argument is the invocant of the method. This means that self must be either the class or object the method was called on. The methods I am worried about are designed to be operate on the object. So $self is an object.

Now we know a couple of things that we can use for researching this further.

Let's look at what an object is in perl. Checking out perlobj, tells us pretty quickly that a perl object is a reference that knows what package it belongs to. This means that $self is a reference to some other type. Checking the new, we can see that $self is a hash reference. So at line 15 and 22 we want to be accessing values in a hash reference.

We have established that perl thinks we are looking at specific elements in a hash. We have also established that we need to be looking at elements in a hash reference.

Checking perldoc, we find that there are a couple articles on references. Let's read perlreftut because tutorials are often easier to understand. It says that we can access a hash ref element by doing ${$self}{theValue}. Most importantly, it says that this syntax is hard to read, and that we can use $self->{theValue} instead.

This means that we were using the wrong syntax on lines 15 and 22, syntax intended to access a hash--not a hash reference. The strict and warnings pragmas are useful for catching this type of error. Remember that perl has different syntax for accessing array and hash members vs array ref and hash ref members.

Please take the time to carefully read perlreftut, perlref, perlboot, perltoot, and perldsc. They provide explanations about references and how to use them, and how OO Perl works.

TGI says moo

Log In?

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

How do I use this? | Other CB clients
Other Users?
Others having an uproarious good time at the Monastery: (8)
As of 2021-05-10 08:49 GMT
Find Nodes?
    Voting Booth?
    Perl 7 will be out ...

    Results (105 votes). Check out past polls.