2

I currently have the following

# $dog, $cat, $rat are all hash refs

                my %rethash = ('success' => 'Your Cool'); 

                my %ref ={ 'dog' => $dog,  'cat' => $cat,  'mouse' => $rat,
                                'chicken' => ''  };

                my $perlobj = ( \%ref,\%rethash );      

When $perlobj is dumped this is the result

 $VAR1 = {
      'success' => 'Your Cool'
    };

However when warnings are enabled I get the following message

Useless use of reference constructor in void context at ..

I realize there is something terribly wrong with how %ref is assigned using {}, What is wrong with this code? I can't seem to get rid of this warning....

EDIT: Ok I think I figured out whats going on,

my $perlobj = ( \%ref,\%rethash );

This does not merge but results in $perlobj becoming a reference to %rethash, this is obvious after reading your responses.

ingueni
  • 49
  • 1
  • 1
  • 5
  • 4
    You're use `{}` when creating `%ref` when you should be using `()` – RobEarl Jun 02 '15 at 15:38
  • 1
    You also want `my %perlobj = ( %ref,%rethash );` – RobEarl Jun 02 '15 at 15:45
  • 1
    possible duplicate of [How can I combine hashes in Perl?](http://stackoverflow.com/questions/350018/how-can-i-combine-hashes-in-perl) – RobEarl Jun 02 '15 at 15:46
  • You are wildly mixing `()` parens and `{}` as well as hashes and hash-references. And you have found a rare instance of `,` as a sequence operator instead of a list constructor. – Patrick J. S. Jun 02 '15 at 16:02
  • @PatrickJ.S. could you elaborate on the sequence operator? I cannot find that in perldoc. – simbabque Jun 02 '15 at 16:13
  • @simbabque: In the docs it's just called ["comma" operator](http://perldoc.perl.org/perlop.html#Comma-Operator). I was reffering to [this usage of _sequence_](https://en.wikipedia.org/wiki/Comma_operator#Syntax). Admittedly the expresseion "as a sequence operator" is a bit sloppy and could have better been said with “used the `,`-operator for sequencing”, – Patrick J. S. Jun 02 '15 at 18:56

2 Answers2

5

What RobEarl is saying is correct. I'll give an explanation of that and add some more stuff.

Your variable name %ref and the fact that you are using {} kinda implies you want a reference here.

Let's take a look what value we will have in %ref. Consider this example.

use strict; use warnings;
use Data::Printer;
my %foo = { key => 'value' };
p %foo;

This will throw a warning Reference found where even-sized list expected on my Perl 5.20.2. The output will be:

{
    HASH(0x7e33c0)   undef
}

It's a hash with a hashref as the key and undef as a value. HASH(0x07e33c0) is what you get when you look at a hash reference without dereferencing it. (The {} are there because Data::Printer converts the hash to a hashref).

Back to your code, the correct sigil for a reference is $. It does not matter what kind of reference it is. The reference is always a scalar (a pointer to the place in memory where the hash/array/something) is stored.

my $ref = { 
  dog     => $dog,
  cat     => $cat,
  mouse   => $rat,
  chicken => '', # maybe this should be undef?
};

Now you've got a hashref with the values of $dog, $cat, $rat and an empty string.

Now you're assigning a variable named $perlobj, which implies it's an object. Instead you are assigning a scalar variable (the $ makes it a scalar) with a list. If you do that, Perl will only assign the right-most value to the variable.

my $foo = (1, 2, 3); # $foo will be 3 and there's a warning

You are assigning a list of two references. The first one is disregarded and only \$rethash gets assigned. That works because conveniently, $perlobj is a scalar, and references are also scalars. So now $perlobj is a reference of %rethash. That's why your Data::Dumper output looks like %rethash.


I'm not sure what you want to do, so I cannot really help you with that. I suggest you read up on some stuff.

  • perlreftut is useful to learn how references work
  • If you want to do Object Oriented Programming, check out Moose
  • It might also be useful to just go get a book to learn a bit more about basic Perl. Learning Perl by Randal L. Schwartz and Beginning Perl by Curtis Poe are both very good for that
simbabque
  • 53,749
  • 8
  • 73
  • 136
  • Thanks for breaking it down I really appreciate it, I was going through some old code and added warnings to a module and found this error. – ingueni Jun 02 '15 at 17:32
2

You are taking a list of hash references and assigning them to a scalar

my $perlobj = ( \%ref, \%rethash );  # same as  $perlobj = \%rethash

Instead you want to take a reference to a merger of hashes

my $perlobj = { %ref, %rethash };
mob
  • 117,087
  • 18
  • 149
  • 283