【问题标题】:Perl $self in different subsPerl $self 在不同的 subs
【发布时间】:2017-02-01 09:14:25
【问题描述】:

我的 Perl 应用程序中有以下结构

sub new {                                   
    my $self = {};
    $self->{'orcl'} = undef;
    $self->{'cgi'} = CGI->new();
    bless $self;
    return $self;
}

sub getJ {
    my $self = shift;
    my $requestmethod = $self->{'cgi'}->request_method;
    $self->{'orcl'} = dbconnect();
    if($requestmethod eq 'POST') {
        my $testvar = anotherSub();
    }

sub anotherSub {
    my $self = shift;
    my $sth = $self->{'orcl'}->functionToFetchRow();
}

在子“dbconnect”中打开了与数据库的连接。 所以我现在的问题是,我收到错误“无法调用方法“functionToFetchRow()””

如果我这样做了

$self->{'orcl'} = dbconnect();

在子“anotherSub”中它工作得很好。但我只想打开一次与数据库的连接,而不是在我需要的每个 Sub 中打开连接。

那么我的错在哪里?

【问题讨论】:

  • 您在子 getJ 的末尾缺少一个大括号。向我们展示一些您实际看到问题的真实代码。另外,我怀疑您是否向我们提供了完整的错误消息(它可能以 on an undefined value 结尾)。
  • 您应该开始正确缩进您的代码。很难读。您似乎还在同一个包中混合了 OOP 代码和正常功能。如果在该包中定义了sub dbconnect,它应该是一个方法,并且也可以使用$self 调用。如果已导入,则不应导入它,而应使用包含包的完全限定名称,否则稍后它将作为对象上的方法使用。您还应该在sub new 中包含$class(类似于$self,但包含包名称),然后将bless 包含到该类中,否则您以后将无法子类化。
  • 考虑在Code Review 的 Perl 标记中发布您的实际完整代码(或您愿意在 Internet 上公开分享的工作子集),我们会给您关于您的风格的反馈并告诉您如何改进代码。
  • 好的,谢谢。但这是我的完整代码。在 sub dbconnect 我只做 $self->{'orcl'} = AnotherPackage::Orcl->new(schema, user, db, ....) 但是你帮了我很多。我想我现在对如何编写 Perl OOP 有了更多了解。这对我来说有点难,因为我在 2010 年最后一次用 php 而不是 OOP 编程。

标签: perl


【解决方案1】:

无法在未定义的值上调用方法“functionToFetchRow”

此错误消息告诉您$selfundef

您需要将$self 传递给anotherSub,否则它不知道。为此,请使用方法语法。

if($requestmethod eq 'POST') {
    my $testvar = $self->anotherSub();
}

如果这样调用,Perl 会自动将$self 作为第一个参数传递给anotherSub。这就是 Perl 中面向对象的工作原理。

当您执行$self->{'cgi'}->request_method$self->{'orcl'}->functionToFetchRow() 时,您已经在使用完全相同的东西。在这两种情况下,$self(实际上只是一个哈希引用)内部的键都包含对象,->method 调用这些对象的方法,将对象本身作为第一个参数传递。

【讨论】:

  • simbabque 你是我最后的英雄!它有效,在您的帮助下,我对 Perl 的理解更加深刻!谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-12-06
  • 2013-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-17
  • 1970-01-01
相关资源
最近更新 更多