Diemauerdk
Diemauerdk

Reputation: 5948

Perl - Odd number of elements in hash assignment in Constructor

I have some problems calling a constructor with a hash. I get the error:

"Odd number of elements in hash assignment at Sumcheck.pm line 4". Sumcheck.pm looks like this:

package Sumcheck;

sub new {
    my ($debug, $debug_matches,%checkHash) = @_;
    my $self = {};
    $self->{DEBUG} = $debug;
    $self->{DEBUG_MATCHES} = $debug_matches;
    $self->{CHECKRESULT_OK} = "COMPLIANT"; 
    $self->{CHECKRESULT_ERROR} = "NONCOMPLIANT"; 
    $self->{checkHash} = %checkHash;
    #print %checkHash;

    bless($self);
    return $self;
}
1;

And i call it like this(just a random hash):

use Sumcheck;
$debug = 0;
$debug_matches = 1;

%checkHash = (  'The Shining'       => 'Kubrick',
                'Ten Commandments'  => 'DeMille',
                'Goonies'           => 'Donner',);

$sumCheck = Sumcheck->new($debug, $debug_matches, %checkHash);

Why do i get this error? How it is solved?

Thx :)

Upvotes: 1

Views: 3295

Answers (2)

Nikhil Jain
Nikhil Jain

Reputation: 8342

First of all, always use use strict and use warnings in you program.

The program is not working as you expected, becuase whenever you make a object of the class then first parameter is always the instance of the class, so write it like this way:

package Sumcheck;
use strict;
use warnings;

   sub new {
   # $checkhash variable holds the reference of the hash.
   my ($class, $debug, $debug_matches,$checkHash) = @_; #$class would hold the instance
   my $self = {};
   $self->{DEBUG} = $debug;
   $self->{DEBUG_MATCHES} = $debug_matches;
   $self->{CHECKRESULT_OK} = "COMPLIANT";
   $self->{CHECKRESULT_ERROR} = "NONCOMPLIANT";
   $self->{checkHash} = %{$checkHash};
   #print %checkHash;
   bless($self);
   return $self;
   }
   my %test = ( abc => "30"); # for testing
   # pass hash as reference
   my $sumcheck = Sumcheck->new('test', 'test20', \%test ); 
   print"$sumcheck->{DEBUG}"; # for testing
   1; 

Above code will solve your problem.

Upvotes: 1

wholerabbit
wholerabbit

Reputation: 11546

The first implicit argument to a method called like this:

MyPackage->someMethod()

is the name of the package. Eg:

package MyPackage;

sub someMethod {
    print shift;

will yield MyPackage.

The idea WRT to constructors is:

sub new {
    my $class = shift;  # now your $debug would be $_[0], so:
    my $self = { @_ };  # <- replace this with your own details
    bless $self, $class;
}

You don't have to do exactly that, but do you see now why your hash has an odd number of elements? In Sumcheck::new, $debug is not what you think it is (check). Remember, a hash is passed literally as a list like this:

name, value, name, value

So, "Sumcheck" (the package name) gets placed in $debug, 0 gets placed into $debug_matches then the first element of the hash is 1, leading to this:

1 => `The Shining`
'Kubrick' => 'Ten Commandments',
'DeMille' => 'Goonies',
'Donner'  =>  # uneven number of elements error

FYI, the first implicit argument to an object method called this way (the second line):

my $obj = Sumcheck->new(..,.);
$obj->someMethod();

Will be $obj, aka. the $self in the method:

sub someMethod {
    my $self = shift

which is the blessed hash returned by the constructor, new().

Upvotes: 2

Related Questions