2012-11-16 125 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