如何使类的成员成为perl中的对象

时间:2013-02-14 20:26:33

标签: perl oop

你好基本上是perl中的OO编程问题。我希望有两个对象A和B,A包含一个B类型的成员变量。我做了一些测试,但似乎不起作用。有什么想法吗?

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.

3 个答案:

答案 0 :(得分:6)

你忘记了方法的第一个参数。方法的第一个参数始终是调用者。

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;
}

答案 1 :(得分: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;

答案 2 :(得分: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; 
}