【问题标题】:Perl HTML::parser error; Undefined subroutine &main::1Perl HTML::解析器错误;未定义的子程序 &main::1
【发布时间】:2011-10-30 05:51:52
【问题描述】:

我收到了错误

Undefined subroutine &main::1 called at /usr/local/lib/perl/5.10.0/HTML/Parser.pm line 102.

这是我的代码

#open (IN,  "<", "foo.html") or die "can't open source file: $!";

my $p = HTML::Parser->new( api_version => 3,
            start_h => [&start, "tagname, attr, text"],
            text_h  => [&text,  "text"],
            default_h   => [sub { print OUT shift }, "text"],
        );
$p->utf8_mode;
$p->empty_element_tags;
$p->ignore_elements(qw(br));

$p->parse_file("foo.html") or die "parsing failed: $!";
#while (<IN>) {
#    $p->parse($_) || die "parsing failed: $!";
#}
#$p->eof;
#close IN;

正如您在注释掉的部分中看到的那样,我也尝试过直接打开和调用 parse(运气同样不佳)。

文件确实可以正常打开。

Parser.pm line 102 是错误提到的是 parse_file 子例程,特别是调用 ->parse

的行

我不知道 parse 在哪里,它不在 HTML::Parser 中,我也没有在 HTML::Entities 中找到它,这是 HTML::Parser 唯一的依赖项。 =/ 恐怕我现在迷路了,PERL 最深奥的魔法对我来说仍然是个谜。

【问题讨论】:

  • 你在使用use strict; use warnings;吗?
  • fwiw,方法 parse 显然是一个 XS 例程(即它是用 C 实现的)

标签: perl html-parsing


【解决方案1】:

尝试使用\&amp;start\&amp;text

my $p = HTML::Parser->new( api_version => 3,
        start_h => [\&start, "tagname, attr, text"],
        text_h  => [\&text,  "text"],
        default_h   => [sub { print OUT shift }, "text"],
    );

否则,您将传递调用 start()text() 的结果,而不是将它们作为子引用。

【讨论】:

    【解决方案2】:

    在文档中说您应该使用\&amp;start。如果您排除反斜杠,它将使用函数start 的返回值(这将使用@_ 作为参数列表,根据使用&amp; 的正常子例程调用pragma)。这个值可以是1

    这是一个例子:

    C:\perl>perl -we "$c=\&s; sub s { print 'yada' }; $c->();"
    yada
    C:\perl>perl -we "$c=&s; sub s { print 'yada' }; $c->();"
    Undefined subroutine &main::1 called at -e line 1.
    yada
    

    不确定为什么会出现错误,但您可以更改它,看看是否有帮助。

    哦,另外,您似乎没有使用use strict。使用 strict 时,我得到一个更有帮助的错误:

    C:\perl>perl -we "use strict; my $c=&s; sub s { print 'a' }; $c->();"
    Can't use string ("1") as a subroutine ref while "strict refs" in use at -e line
    

    【讨论】:

    • 谢谢,引用子工作! Strict 正在使用 =/ 但这整件事太奇怪了,我很高兴它现在可以工作了。
    • @Nick Johnson:严格是词法范围的;显然 HTML/Parser.pm 没有使用它
    • @ysth 奇怪的是,HTML/Parser.pm 使用的是严格的。
    • @TLP @ysth 但是回调是用 C 语言而不是 perl 进行的(parse 是 XS 例程),所以如果没有观察到这种限制是可以理解的。
    猜你喜欢
    • 2011-10-08
    • 2015-10-22
    • 2016-08-29
    • 2013-06-25
    • 2017-02-23
    • 1970-01-01
    • 2011-07-03
    • 2017-03-28
    • 2011-04-17
    相关资源
    最近更新 更多