【问题标题】:Weird scope error in a module模块中的奇怪范围错误
【发布时间】:2014-07-17 07:29:53
【问题描述】:

我正在编写一个继承自 HTML::Parser 的 Perl 模块,但我收到了一个编译错误,我从昨天开始就无法解决。这是代码:

#!/usr/bin/perl
# HTML::Parser : The inheriting module
# Fetches all links and their text from a HTML file

use warnings;
use strict;
use HTML::Entities;

package AnchorTextParser;

use base 'HTML::Parser';

our $betweenAnchor;
our $linkAdress;
our %anchorTexts;


sub start {
    my (undef, undef, $attr) = @_;
    if( $attr->{href} && not ($attr->{href} =~ /mailto/i) ) {
        $betweenAnchor = 1;
        $linkAdress = $attr->{href};
    }
}

sub end {
    $betweenAnchor = 0;
}

sub text {
    if( $betweenAnchor ) {
        my $origText;
        (undef, $origText) = @_;
        #print decode_entities($origText) . "\n";
        %anchorTexts{$linkAdress} = decode_entities($origText); 
    }
}

sub getAnchorTexts {
    return\%anchorTexts;
}

1;

我加载模块时遇到的错误是:

syntax error at AnchorTextParser.pm line 34, near "%anchorTexts{" 
Global symbol "$origText" requires explixit package name at AnchorTextParser.pm line 34.
syntax error at AnchorTextOarser.pm line 36, near "}"
Compilation failed in require at module_loader.pl line 6.
BEGIN failed--compilation aborted at module_loader.pl line 6. 

为了避免混淆,这是模块加载器中发生的事情:

#!/usr/bin/perl
# HTML::Parser : The test script

use warnings;
use strict;
use AnchorTextParser;

这是我第一次在 Perl 中编写继承模块,所以这很可能是我做错了什么。但是错误是如此的难以描述,而且显然是错误的($origText 不是全局的,并且非常明确地定义为“我的”..),以至于我无法弄清楚错误是什么。 非常感谢任何帮助。

【问题讨论】:

    标签: perl inheritance html-parsing


    【解决方案1】:

    通过将% 更改为$ 来修复第34 行对anchorTexts 变量的引用:

        $anchorTexts{$linkAdress} = decode_entities($origText); 
    

    【讨论】:

    • 嗯,结果比我想象的还要简单。非常感谢,它解决了这个问题。
    • 现在该行将编译,耶!但是在运行时还是会失败,因为他将decode_entities函数导入了错误的包中。
    • @tobyink 我是如何将它导入错误的包中的?我得到了错误 iirc,但我通过使用 HTML::Entities::decode_entities($origText); 调用函数来“解决”它我应该如何或在哪里导入它?函数内?所有重载函数都是基类作用域/命名空间的一部分吗?
    • 导出函数的模块将它们导出到包中,而不是词法范围。 (虽然现在 Perl 5.18 已经给了我们词法 subs,这可能会开始改变。)这意味着你应该导入 HTML::Entities below package 行,以便将函数导入到AnchorTextParser 包。通过 import above package,它会将 HTML::Entities 导入 AnchorTextParser 的 caller。 (但不可靠。StackOverflow cmets 太短,无法解释原因。)strictwarnings 偶然具有完全的词法范围,因此可以安全地导入 above package
    • 感谢您澄清这一点。总是乐于学习新的语言 =)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-03-16
    • 2016-11-30
    • 1970-01-01
    • 2013-07-05
    • 2013-10-29
    • 2012-02-23
    • 1970-01-01
    相关资源
    最近更新 更多