2012-11-16 124 views
8

我有一个名为RuleObject的基础对象和一个从名为RuleObjectString继承的对象。我在RuleObjectString中有一个新方法,我想在使用该对象的代码中调用它。但我得到错误。 '通过包“RuleObject”在./testobject.pl第10行找不到对象方法“比较”。'但我没有创建一个RuleObject。我正在创建一个RuleObjectString。我在这里做错了什么?在Perl中扩展对象

testobject.pl

1 #! /usr/bin/perl 
    2 
    3 use strict; 
    4 
    5 use RuleObjectString; 
    6 
    7 my $s = RuleObjectString->new(); 
    8 $s->value('stuff goes here'); 
    9 
10 if ($s->compare('stuff')){ 
11   print "MATCH!\n"; 
12 }else{ 
13   print "no match :(\n"; 
14 } 

RuleObject.pm

package RuleObject; 

our @ISA = qw/Exporter/; 
our @EXPORT = qw/new/; 

use strict; 

sub new{ 
     my $class = shift; 

     my $self; 
     $self->{value} = undef; 

     bless $self; 
     return $self; 
} 

sub value{ 
     my $self = shift; 
     my $value = shift; 
     if ($value){ 
       $self->{value} = $value; 
     }else{ 
       return $self->{value}; 
     } 
} 

RuleObjectString.pm

package RuleObjectString; 

our @ISA = qw/RuleObject/; 
our @EXPORT = qw/compare/; 

use strict; 

sub compare{ 
     my $self = shift; 
     my $compareto = shift; 

     return $self->value() =~ /$compareto/; 
} 
+6

您不应该'@ EXPORT'您的类和实例方法,并且您的模块通常不应该继承'Exporter',除非它们具有真正的导出过程函数。 – pilcrow

+0

对于需要导出*函数*的情况,'Sub :: Exporter'比'Exporter'好得多。但是,您应该避免从也是类定义的包中导出函数。 ' –

回答

12

我认为jmcneirney是在正确的轨道上。在你RuleObject构造函数,你说

bless $self; 

这是一样的

bless $self, __PACKAGE__; 

bless $self, 'RuleObject' 

,但你想要的是为对象,以祝福为RuleObjectString。所以,你想要做的是说

bless $self, $class 

现在

RuleObject->new() 
RuleObjectString->new() 

都将调用相同的构造,但第一次调用返回的对象将被祝福的RuleObject和第二物体会祝福RuleObjectString

+0

这个伎俩!谢谢! – Mike

0

尝试倾销的对象,看看它是什么。

print Dumper($s) 

这将是一个RuleObject。

您可能需要在RuleObjectString 中定义一个new(),并让它调用Super :: new()。

+0

没有必要;该错误如前所述。也就是说,使用不合格的'bless()'来祝福调用包,而不是提供的类名。 – LeoNerd

5

这是2012年,所以你应该考虑使用适当的OOP解决方案,而不是重新发明轮子。

使用Moose,该解决方案将是这个样子(未经测试):

RuleObject.pm

package RuleObject; 
use Moose; 

has 'value' => (isa => 'Str', is => 'rw', required => 0, default => ''); 

1; 

RuleObjectString.pm

package RuleObjectString; 
use Moose; 

extends 'RuleObject'; 

sub compare { 
    my $self  = shift; 
    my $compareto = shift; 

    return $self->value =~ /$compareto/; 
} 

1; 

简单! :)

+2

对于那些认为'Moose'太重的人来说,'Moo'是一个很好的轻量级选择。 –

+1

理解语言的工作原理并不是很好,不仅仅依赖于图书馆解决方案吗? (2014年和世界几乎与开发者冲突)。 – jackyalcine

+0

OP想解决一个特定的问题,而不是学习Perl。这些图书馆有很好的理由。 :) – toreau