【问题标题】:Can't locate object method XX via package "1"无法通过包“1”定位对象方法 XX
【发布时间】:2015-12-10 04:49:13
【问题描述】:

我很清楚有几个关于类似主题的问题,但我看不到如何将答案应用于我的问题:

我不明白的是,我在两个包中使用了相同的架构,而在第一个包中没问题......包“1”来自哪里?

这是运行良好的包:

package ObjA;
use warnings;
use strict;
use Data::Dumper;
use Carp;
use ObjB;

#CONSTRUCTOR AND INITIALISATION
sub new {
    my $class = shift;
    my $self = {@_};
    bless($self,$class);
    $self->language();
    return $self;
}
sub load {
    my $self = shift;
    open (my $stream,"<",$self ->{name});
    my @glob_xs=();
    my $i = 0;
    while (<$stream>){
        $i += 1;
        my @x = extract($stream,());
        @glob_xs=(@glob_tokens,@x);
    }
    $self->tokens(\@glob_xs);
}

sub extract{
    my ($stream,@x) = @_;
    my $line = <$stream>;
    chomp $line;
    if ($line =~ /^\s*$/){
        return @x;
    }
    print join("/",split("\t",$line));
    my $b = ObjB::new(split("\t",$line));
    push @x,$b->form;
    extract_sentence($stream,@x);
}

# OBJECT ACCESSOR METHODS
sub language {$_[0]->{language}=$_[1] if defined $_[1] ; $_[0]->{language}} 

1;

这是产生错误的原因:

package ObjB;
use warnings;
use strict;
use Data::Dumper;
use Carp;

# CONSTRUCTOR AND INITIALISATION
sub new {
    my $class = shift;
    my $self = {@_};
    bless($self,$class);
    $self->idx();              # Dies here.
    return $self;
}

# OBJECT ACCESSOR METHODS
sub idx {$_[0]->{idx}=$_[1] if defined $_[1] ; $_[0]->{idx}}
1;

会不会是因为 ObjB 在 ObjA 内部被调用?还是因为它们是在两个不同的文件中声明的?

我真的希望有人能给出答案,因为我一直在兜圈子......

谢谢!!

【问题讨论】:

  • ObjB::new 看起来很可疑

标签: perl


【解决方案1】:

Obj::new 是一个方法,但是你把它当作一个子程序来调用。

ObjB::new(split("\t",$line));

这导致该行的第一个字段的值被用作类,并且该值可能是1。您可能打算使用

ObjB->new(split("\t",$line));

【讨论】:

  • 好的,谢谢,效果很好!! (但我仍然不明白其中的微妙之处:我在项目的主文件中使用了 ObjA::new() 并且没有引发错误......这是 context main 与 class 的区别吗?)
  • 几个错误结合在一起发生了正确的结果。 ObjA::new() 是错误的,但是由于您没有传递任何参数,因此 $class 最终成为 undef,而 bless 认为您指的是当前包 (ObjA)。换句话说,ObjA::new() 恰好等价于ObjA::new('ObjA'),而后者恰好等价于ObjA-&gt;new()。但情况并非总是如此。你刚刚得到了“幸运”。
  • 谢谢,很高兴有解决方案的解释,我现在明白了!! (这就是我的全部:短期幸运......)
  • @stevieb 不,ObjB::new 只是一个常规的子程序调用。 new ObjBindirect object notation
  • @stevieb,间接对象表示法是方法调用的替代语法(您应该避免)。 method $i @args$i-&gt;method(@args) 的间接版本。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-08-05
  • 2012-06-08
  • 1970-01-01
  • 2013-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多