2013-02-14 84 views
1

你好,基本上它是一個Perl中面向對象編程的問題。我想有兩個對象A和B,而A包含一個B類型的成員變量。我做了一些測試,但似乎不起作用。任何想法?如何在perl中使一個類的成員成爲一個對象

a.pm

package a; 


sub new{ 
    my $self = {}; 
    my $b = shift; 
    $self->{B} = $b; 
    bless $self; 
    return $self; 
} 

sub doa{ 
    my $self = shift; 
    print "a\n"; 
    $self->{B}->dob; 
} 

1; 

b.pm

package b; 

sub new { 
    my $self = {}; 
    bless $self; 
    return $self; 
} 

sub dob{ 
    my $self = shift; 
    print "b\n"; 
} 



1; 

test.pl

use a; 
use b; 

my $b = b->new; 
my $a = a->new($b); 
$a->doa; 

當我跑了這一點,它表明:

a 
Can't locate object method "dob" via package "a" at a.pm line 16. 

回答

6

你忘了該方法的第一個參數。方法的第一個參數始終是invocant。

sub new { 
    my ($class, $b) = @_; 
    my $self = {}; 
    $self->{B} = $b; 
    return bless($self, $class); 
} 

我通常bless第一,雖然

sub new { 
    my ($class, ...) = @_; 
    my $self = bless({}, $class); 
    $self->{attribute} = ...; 
    return $self; 
} 

,因爲它是一個派生類的構造函數更加一致。

sub new { 
    my ($class, ...) = @_; 
    my $self = $class->SUPER::new(...); 
    $self->{attribute} = ...; 
    return $self; 
} 
+0

在我的答案中添加了樣式註釋。 – ikegami 2013-02-17 10:15:21

4

您可能希望使用類似Moose或其更輕的表親Moo來使Perl OO更容易。你也可能喜歡(免費)Modern Perl Book瞭解更多現代Perl提供的許多新的和令人興奮的東西!

#!/usr/bin/env perl 

use strict; 
use warnings; 

package ClassA; 

use Moo; 

has 'b' => (
    is => 'ro', 
    isa => sub { shift->isa('ClassB') or die "Need a ClassB\n" }, # not necessary but handy 
    required => 1, 
); 

sub doa { 
    my $self = shift; 
    print "a\n"; 
    $self->b->dob; 
} 

package ClassB; 

use Moo; 

sub dob { 
    my $self = shift; 
    print "b\n"; 
} 

package main; 

my $b = ClassB->new; 
my $a = ClassA->new(b => $b); 
$a->doa; 

事實上,這取決於你想要什麼,也許你甚至可能要像代表團:

#!/usr/bin/env perl 

use strict; 
use warnings; 

package ClassA; 

use Moo; 

has 'b' => (
    is => 'ro', 
    isa => sub { shift->isa('ClassB') or die "Need a ClassB\n" }, # not necessary but handy 
    required => 1, 
    handles => ['dob'], 
); 

sub doa { 
    my $self = shift; 
    print "a\n"; 
} 

package ClassB; 

use Moo; 

sub dob { 
    my $self = shift; 
    print "b\n"; 
} 

package main; 

my $b = ClassB->new; 
my $a = ClassA->new(b => $b); 
$a->doa; 
$a->dob; 
+0

無法更改 「ISA」 爲'ISA => 'ClassB的','? – gpojd 2013-02-14 21:01:55

+0

如果您正在使用Moose,但不在Moo中。它是少數幾個區別之一,說實話,我通常在使用Moo時忽略'isa'檢查。 – 2013-02-14 21:03:04

2

您不是blessing your objects正確。試試這個:

答:

sub new {                                                
    my $class = shift;                                             
    my $b = shift;                                              
    return bless { B => $b }, $class;                                         
} 

B:

sub new { 
    my $class = shift; 
    return bless {}, $class; 
} 
相關問題