Home > OS >  An Object Accesses its own Attributes in Another Method
An Object Accesses its own Attributes in Another Method

Time:11-09

Perl newbie here. I've been Googling for hours on what I thought would be a relatively simple problem. Suppose I have this code:

#!/usr/bin/perl
use warnings;
use strict;

package Guy;
sub new {
        my $type = shift;
        my %params = @_;
        my $self = {};
        $self->{'First'} = $params{'First'};
        $self->{'Middle'} = $params{'Middle'};
        $self->{'Last'} = $params{'Last'};
        bless $self, $type;
}
sub printMe
{
        printf "-----------------------------------\n";
        printf "My type is: \"$self->{type}\"\n";        # Line 18
        printf "First  ::  $self->{First}\n";            # Line 19
        printf "Middle ::  $self->{Middle}\n";           # Line 20
        printf "Last   ::  $self->{Last}\n";             # Line 21
        printf "-----------------------------------\n";
}

package main;
my $dude = Guy->new( 'First' => "John", 'Middle' => "Jacob", 'Last' => "Smith" );
$dude->printMe();

Output is:

me@ubuntu1$ ./toy01.perl
Global symbol "$self" requires explicit package name (did you forget to declare "my $self"?) at ./toy01.perl line 18.
Global symbol "$self" requires explicit package name (did you forget to declare "my $self"?) at ./toy01.perl line 19.
Global symbol "$self" requires explicit package name (did you forget to declare "my $self"?) at ./toy01.perl line 20.
Global symbol "$self" requires explicit package name (did you forget to declare "my $self"?) at ./toy01.perl line 21.
Execution of ./toy01.perl aborted due to compilation errors.
me@ubuntu1$

So the problem here is that class method printMe() can't access attributes stored in the $self hash, which is populated in the constructor. I'm so confused as to why.

In the constructor, $self is created as a hash, used to store the attributed passed into the constructor. Is $self created with a local scope when it needs to be global, or something like that? Or do I lack a command at the top of the printMe() method that makes $self visible, or something?

And how to refer to attribute type, which is an attribute that is set in the constructor but not stored in the $self hash? (My $self->{type} call is obviously a desperate attempt to stumble upon the solution here.) Any advice or feedback is appreciated here, thank you.

CodePudding user response:

The object is sent to the method as the first parameter, but you need to populate the variable yourself:

sub printMe
{
    my ($self) = @_;
    ...

Note that $self->{type} doesn't exist. Use ref $self or blessed($self) from Scalar::Util.

Also, using printf without a format string is useless. Use print or say instead, or use printf properly:

printf "First  ::  %s\n", $self->{First};
  • Related