引用找到Perl中预期的偶数大小的列表 - 可能的传递引用错误?

时间:2013-06-25 13:04:51

标签: perl oop hash pass-by-reference hashref

我创建了一个Perl类/模块来显示圣经经文。在其中有一个存储多个经文的哈希,其中键是书/章/诗,而值是文本。此哈希值从模块返回。

我将圣经课程包含在控制器课程中,这种联系似乎有效。问题是我在执行时遇到错误。我的IDE是因为我正在使用Lynda教程,是带有EPIC插件的Eclipse。

错误是:

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)  => 

这是CONTROLLER类:

#!/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");
    }
}

这是返回经文的类,并且有选择随机经文的方法:

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

我做错了什么?我怀疑它与哈希引用和哈希引用有关,但我不知道如何修复它。我的解除引用尝试失败了,因为我真的不知道我在做什么。我模仿了我在perlmonks上看到的随意的吸气剂。 #$knockknocks{(keys %knockknocks)[rand keys %knockknocks]};

4 个答案:

答案 0 :(得分:7)

总的来说,你有:

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

但是,在package EHW_BibleInspiration;中,方法getBibleObj会返回:return $bibleObj_ref;

你做的主要是:my $bo_ref = $o->getBibleObj();

然后拨打listHash($bo_ref);

最后,不要忘记将sub listHash更改为:

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

答案 1 :(得分:6)

main,你做

listHash(\%bo_ref);

这会将哈希引用传递给sub。但是,它尝试解压缩其参数,如

my %hash = @_;

哎呀,它想要哈希。

  1. 要么我们传递一个哈希:listHash(%bo_ref)。这为我们节省了很多打字。
  2. 或者,我们处理子内部的引用,如

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

    请注意引用如何使用取消引用箭头->来访问哈希条目,以及如何将其解除引用keys的哈希值。

答案 2 :(得分:1)

我怀疑你的怀疑是正确的。在您的方法sub listHash中,您正确地传入了哈希,但是您尝试使用哈希而不是内部变量的哈希引用。尝试使用my ($hash) = @_;代替my %hash = @_;

使用引用时,您可以使用->运算符取消引用它以获取基础值。您的方法的其余部分应如下所示:

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

在你的程序的第43行,我必须通过调用keys %{$hash}告诉Perl引用应该是哈希引用。然后在第44行,我通过调用$hash->{$key}取消引用哈希以获得正确的值。有关Perl和参考的更多信息,您可以阅读tutorial

答案 3 :(得分:0)

listHash期待一个哈希,你传递一个哈希引用。变化:

listHash(\%bo_ref);

为:

listHash(%bo_ref);