9

我创建了一个 Perl 类/模块来显示圣经经文。其中有一个散列存储了几节经文,键是书/章/节,值是文本。这个哈希是从模块返回的。

我在控制器类中包含圣经类,并且这种连接似乎有效。问题是我在执行时不断出错。因为我正在学习 Lynda 教程,所以我的 IDE 是带有 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)  => 

这是控制器类:

#!/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

4 回答 4

8

总的来说,你有:

 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");
    }
}
于 2013-06-25T13:41:54.280 回答
6

在你的main,你做

listHash(\%bo_ref);

这会将哈希引用传递给子。然而,它试图解开它的论点,比如

my %hash = @_;

糟糕,它需要一个哈希。

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

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

    请注意引用如何使用取消引用箭头->来访问哈希条目,以及它如何被取消引用到keys.

于 2013-06-25T13:09:33.050 回答
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 行,我必须通过调用来告诉 Perl 引用应该是哈希引用keys %{$hash}。然后在第 44 行,我通过调用取消引用哈希来获得正确的值$hash->{$key}。有关 Perl 和参考资料的更多信息,您可以阅读整个教程

于 2013-06-25T13:13:12.730 回答
0

listHash期待一个散列,而您正在向它传递一个散列引用。改变:

listHash(\%bo_ref);

至:

listHash(%bo_ref);
于 2013-06-25T13:10:01.177 回答