【问题标题】:Variable $self in Perl is undefinedPerl 中的变量 $self 未定义
【发布时间】:2014-09-17 18:11:48
【问题描述】:

我正在编写一个使用 Perl 模块 Module.pm 的 Perl 脚本。

Module.pm 是这样的:

package Module;
use strict;
use warnings;

sub getInfo {

    my $self = shift;
    #my $var = shift;

    if (!$self)
    {
        my $errmsg = "My ERROR MESSAGE";
        return [1, $errmsg];
    }

    return [1, $self];
}1;

我这样称呼它:

use Module

my $result = Module::getInfo();

但我在第 # 行不断收到一个 FATAL ERROR (at Module.pm) undefined object。这是为什么呢?

此外,如果我删除 getInfo() 子例程中的第一个注释并将另一个参数添加到我的调用行,那么我不会收到相同的错误。为什么?我以为我不必将 Module 对象作为参数发送来调用子例程?

这是一个使用 Perl 5.8.8 的 Linux 服务器。

【问题讨论】:

  • Module.pm did not return a true value at script.pl line 3. — 如果您在构建简化的测试用例时不引入新的错误,这真的很有帮助。
  • 抱歉,您不需要加一个 1;到模块的末尾?
  • 模块顶部的package 行怎么样?
  • 你有use strict;use warnings;吗?

标签: perl arguments undefined self perl5.8


【解决方案1】:

当您调用包的成员函数时,仅当您使用-> 表示法时,包名称才会作为隐式第一个参数传递。这称为“方法调用”;它还可以搜索类层次结构以确定调用什么。如果前缀是类名,则隐含的第一个参数是包的名称,作为字符串。如果前缀是对象引用,则隐含的第一个参数是该对象引用。

使用:: 表示法,这是一个没有隐式第一个参数的普通子例程调用。

例如:

% cat foo.pl
#!/usr/bin/perl

use strict;
use warnings;
use v5.10;

package M {
    sub getInfo {
        my($self) = shift;
        say "\$self = ", ($self // 'undef');
    }

    1;
};

M::getInfo();
M->getInfo();
% ./foo.pl
$self = undef
$self = M
% 

Module::getInfo() 更改为Module->getInfo()

Perl 文档中对此进行了更详细的讨论:

旧版本的 Perl 有 perltootperlboot 教程;自 5.20(或可能更早)起,它们已被 perlootut 取代。

【讨论】:

  • 非常感谢,我爱你,它成功了,我已经坚持了太久了!
  • 那么像 '::' 和 '->' 这样调用模块有什么区别。
  • -> 传递一个隐式的第一个参数。 :: 没有。
  • -> 也会调用继承的方法。
  • Foo()(或Bar::Foo())是一个子程序调用。 $o->Foo()(或$o->Bar::Foo())是一个方法调用。方法调用以调用者(-> 的 LHS)作为参数提供,并搜索类层次结构以查找方法。
猜你喜欢
  • 1970-01-01
  • 2015-12-20
  • 1970-01-01
  • 2012-12-13
  • 2011-02-27
  • 2011-06-11
  • 2015-03-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多