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};