SL07
SL07

Reputation: 103

Odd Number of elements in hash assignment in subroutine parameter

I want to pass a hash and $dbh to my sub save2db. However, I am getting an error message: Odd number of elements in hash assignment in file2.pm after this line of code: my (%resultHash, $dbh) = (@_);. Can someone please explain to me the cause of this error. Thanks in advance!

file1.pl

my $dbh_global = connect2db();
my %hash; ##Assume there are nothing wrong with the hash and it is populated

foreach my $fileName_input (@ARGV){
    NVD::save2db(%hash, $dbh_global);
}

sub connect2db{
    my $driver = "mysql";
    my $database = "test";
    my $dsn = "DBI:$driver:database=$database";
    my $userid = "root";
    my $password = "";

    my $dbh = DBI->connect($dsn, $userid, $password) or die $DBI::errstr;

    return $dbh;  
}

file2.pm

sub save2db{

    my (%resultHash, $dbh) = (@_); # <-Error message occured

    foreach my $resultHash_entry (keys %resultHash){
        my $a= $resultHash{$resultHash_entry}{'a'};
        my $b= $resultHash{$resultHash_entry}{'b'};
        my $c= $resultHash{$resultHash_entry}{'c'};
        my $d= $resultHash{$resultHash_entry}{'d'};

        my $insert_sql = $dbh -> prepare("INSERT INTO `test`.`record`
                                       (`a`, `b`, `c`, `d`)
                                       VALUES
                                       (?, ?, ?, ?)");

        $insert_sql->execute($a, $b, $c, $d) or die $DBI::errstr;
    }

}

Upvotes: 1

Views: 2242

Answers (1)

mkHun
mkHun

Reputation: 5927

Odd number of elements in hash assignment is not an error but a warning. The problem rises because when the values are passed to the subroutine, the values gets flattened together.

Let us consider your hash have some data for example

%hash = ("a"=>1,"b"=>2);

and $dbh_global = "abc"

Then you pass the value into the subroutine,

 NVD::save2db(%hash, $dbh_global); #the problem is here. 

Hash will always have a key with value. So every hash will have only even data.

you retrieve the value into the subroutine like,

my (%resultHash, $dbh) = (@_);

So %resultHashwill contain uneven values, three keys and two values like this

{
  a=>1,
  b=>2,
  abc           #This is the reason of the warning. 
}

and then $dbh has no value in it.

so Change the line as

NVD::save2db($dbh_global, %hash);

and retrieve the values into subroutine like

my ($dbh,%resultHash) = (@_);

Or else

use hash reference for to do it.

my $resulthash_ref = \%resultHash; #Hash reference 

NVD::save2db($resulthash_ref, $dbh_global);


#inside the subroutine 
{
    my ($hash_ref,$dbh) = (@_);
    my %hash = %{$hash};  #Dereference the hash
}

Upvotes: 4

Related Questions