Reference found where even-sized list expected in Perl - Possible pass-by-reference error?

Eric Hepperle - CodeSlayer2010 picture Eric Hepperle - CodeSlayer2010 · Jun 25, 2013 · Viewed 24.5k times · Source

I have a Perl class/module that I created to display Bible verses. In it there is a hash that stores several verses, with the key being the book/chapter/verse and the value being the text. This hash is returned from the module.

I'm including the Bible class in a controller class, and that connection seems to work. The problem is I keep getting errors on executing. My IDE because I'm following a Lynda tutorial, is Eclipse with the EPIC plugin.

The error is:

Reference found where even-sized list expected at C:/Documents and Settings/nunya/eric.hepperle_codebase/lynda/lamp/perl5/Exercise Files/14 Modules/eh_bibleInspiration_controller.pl line 42.
Use of uninitialized value $value in concatenation (.) or string at C:/Documents and Settings/nunya/eric.hepperle_codebase/lynda/lamp/perl5/Exercise Files/14 Modules/eh_bibleInspiration_controller.pl line 45.
HASH(0x19ad454)  => 

Here is the CONTROLLER class:

#!/usr/bin/perl
# eh_bibleInspiration_controller.pl by Eric Hepperle - 06/23/13
#

use strict;
use warnings;

use Data::Dumper;
use EHW_BibleInspiration;

main(@ARGV);

sub main
{
    my $o = EHW_BibleInspiration->new; # instantiate new object.
    my %bo_ref = $o->getBibleObj();
    print "\$o is type: " . ref($o) . ".\n";
    print "\%bo_ref is type: " . ref(\%bo_ref) . ".\n";
#    exit;

    $o->getVerseObj();
    listHash(\%bo_ref);

    message("Done.");
}

sub message
{
    my $m = shift or return;
    print("$m\n");
}

sub error
{
    my $e = shift || 'unkown error';
    print("$0: $e\n");
    exit 0;
}

sub listHash
{
    my %hash = @_;
    foreach my $key (sort keys %hash) {
        my $value = $hash{$key};
        message("$key  => $value\n");
    }
}

Here is the class that returns the verses and has the method to pick a random verse:

# EHW_BibleInspiration.pm
#   EHW_BibleInspiration.
#

package EHW_BibleInspiration;
use strict;
use warnings;
use IO::File;
use Data::Dumper;

our $VERSION = "0.1";

sub new
{
    my $class = shift;
    my $self = {};
    bless($self, $class); # turns hash into object
    return $self;
}

sub getVerseObj
{
    my ($self) = @_;

    print "My Bible Verse:\n";
    my $verses = $self->getBibleObj();
    # get random verse
    #$knockknocks{(keys %knockknocks)[rand keys %knockknocks]};

    #  sub mysub {
    #    my $params = shift;
    #    my %paramhash = %$params;
    #  }

#    my %verses = %{$verses};
#    my $random_value = %verses{(keys %verses)[rand keys %verses]};
#    print Dumper(%{$random_value});
}

sub getBibleObj
{
    my ($self) = @_;

    # create bible verse object (ESV)
    my $bibleObj_ref = {
        'john 3:16'         => 'For God so loved the world,that he gave his only Son, that whoever believes in him should not perish but have eternal life.',
        'matt 10:8'         => 'Heal the sick, raise the dead, cleanse lepers, cast out demons. You received without paying; give without pay.',        
        'Luke 6:38'         => 'Give, and it will be given to you. Good measure, pressed down, shaken together, running over, will be put into your lap. For with the measure you use it will be measured back to you.',              
        'John 16:24'        => 'Until now you have asked nothing in my name. Ask, and you will receive, that your joy may be full.',        
        'Psalms 32:7'       => 'You are a hiding place for me; you preserve me from trouble; you surround me with shouts of deliverance. Selah',
        'Proverbs 3:5-6'    => 'Trust in the LORD with all your heart, and do not lean on your own understanding. 6 In all your ways acknowledge him, and he will make straight your paths.',
        'John 14:1'         => 'Let not your hearts be troubled. Believe in God; believe also in me.'
    };

    my $out = "The BIBLE is awesome!\n";

    return $bibleObj_ref;
}

1;

What am I doing wrong? I suspect it has something to do with hash vs hash reference, but I don't know how to fix it. My dereferencing attempts had failed miserably because I don't really know what I'm doing. I modeled my random getter off of something I saw on perlmonks. #$knockknocks{(keys %knockknocks)[rand keys %knockknocks]};

Answer

Toto picture Toto · Jun 25, 2013

In the main, you have:

 my %bo_ref = $o->getBibleObj();

but, in package EHW_BibleInspiration;, the method getBibleObj returns : return $bibleObj_ref;

You'd do, in the main : my $bo_ref = $o->getBibleObj();

and then call listHash($bo_ref);

Finaly, don't forget to change sub listHash to:

sub listHash
{
    my ($hash) = @_;
    foreach my $key (sort keys %{$hash}) {
        my $value = $hash->{$key};
        message("$key  => $value\n");
    }
}