perl继承和目录结构

时间:2015-06-18 21:14:57

标签: perl

我正在尝试学习Perl中的继承。

这是我的目录结构:
perldir
perldir \ child.pl
perldir \ MYLIB
perldir \ MYLIB \ Parent.pm

Parent.pm

package Parent;

sub new { 
    my $class = shift;
    my $self = { _first => shift, _last => shift };
    bless $self, $class;
}

sub getFirstName {
    my ($self) = @_;
    return $self->{ _first };
}

1;

child.pl

package Child;

use parent 'Mylib::Parent';

sub new { 
    my $class = shift;
    my $self = Parent->new( shift, shift );
    bless $self, $class;
}

my $obj = new Child('Jack', 'Sparrow');
print $obj->{_first},' ',$obj->{_last};
print "\n",$obj->getFirstName();  #Error

最后一行抛出的错误是:无法通过child.pl第13行的包“AChild”找到对象方法“getFirstName”;

如果我执行以下操作之一,该程序将起作用:
1.我在Mylib目录下有两个文件 2.我替换

use parent 'Mylib::Parent'

use Mylib::Parent;
@ISA = ('Parent');

是否可以使用'use parent'和子类在不同的目录中使程序工作?

==========================
根据choroba的答案更新了问题

好的,我更改了类以反映以下内容:

Parent.pm

package Mylib::Parent;

sub new { 
    my $class = shift;
    my $self = { _first => shift, _last => shift };
    bless $self, $class;
}

sub getFirstName {
    my ($self) = @_;
    return $self->{ _first };
}

1;

child.pl

package Child;

use parent 'Mylib::Parent';

sub new { 
    my $class = shift;
    my $self = Mylib::Parent->new( shift, shift );
    bless $self, $class;
}

my $obj = new Child('Jack', 'Sparrow');
print $obj->{_first},' ',$obj->{_last};
print "\n",$obj->getFirstName();

以上工作正常。现在考虑我希望另一个子类与Parent.pm。

位于同一目录中

perldir \ MYLIB \ ChildTwo.pl

package ChildTwo;   #or package Mylib::ChildTwo;

use parent 'Mylib::Parent'; #or use parent 'Parent';

sub new { 
    my $class = shift;
    my $self = Mylib::Parent->new( shift, shift ); #or Parent->new(shift, shift);
    bless $self, $class;
}

my $obj = new ChildTwo('Jack', 'Sparrow'); #or new Mylib::ChildTwo('Jack','Sparrow');
print $obj->{_first},' ',$obj->{_last};
print "\n",$obj->getFirstName();

1;

以上不起作用。我可以让ChildTwo.pl与Child.pl一起使用而不使用'use lib'吗?

3 个答案:

答案 0 :(得分:3)

您必须下定决心:父包名称为Parent,然后是child.pl

use parent 'Parent';

告诉perl在哪里搜索它:

perl -IMylib child.pl

或使用lib

use FindBin;
use lib "$FindBin::Bin/Mylib";

或者,包的名称是Mylib::Parent,那么你必须修改包声明:

package Mylib::Parent;

并调用正确的构造函数:

my $self = Mylib::Parent->new( shift, shift );

答案 1 :(得分:0)

我的目标是了解类在驻留在各种包中时如何相互使用。看来,与Java不同的是,' lib'通常表示第三方jar,Perl中的lib表示包含特定于脚本的所有包的根。

  

似乎'使用lib(dirpath)' 必须使用。 查看用法   ChildThree.pm

目录结构:

/perldir/child.pl
/perldir/use_child_two.pl
/perldir/use_child_three.pl
/perldir/Mylib/Parent.pm
/perldir/Mylib/ChildTwo.pm
/perldir/Secondlib/ChildThree.pm

<强> /perldir/Mylib/Parent.pm

package Mylib::Parent;

sub new { 
    my $class = shift;
    my $self = { _first => shift, _last => shift };
    bless $self, $class;
}

sub getFirstName {
    my ($self) = @_;
    return $self->{ _first };
}

1;

<强> /perldir/child.pl

package Child;

use parent 'Mylib::Parent';

sub new { 
    my $class = shift;
    my $self = Mylib::Parent->new( shift, shift );
    bless $self, $class;
}

my $obj = new Child('Jack', 'Sparrow');
print $obj->{_first},' ',$obj->{_last};
print "\n",$obj->getFirstName();

<强> /perldir/Mylib/ChildTwo.pm

package Mylib::ChildTwo;

use parent 'Mylib::Parent';

sub new { 
    my $class = shift;
    my $self = Mylib::Parent->new( shift, shift );
    bless $self, $class;
}

1;

<强> /perldir/use_child_two.pl

use Scalar::Util ('blessed');

use Mylib::ChildTwo;

my $obj = new Mylib::ChildTwo('Jack', 'Sparrow');
print "\n Class: ", blessed ( $obj );
print "\n ",$obj->{_first},' ',$obj->{_last};
print "\n ",$obj->getFirstName();

1;

<强> /perldir/Secondlib/ChildThree.pm

package Secondlib::ChildThree;

use lib '/perldir';     #Adds directories to search path to discover 
                        #package structure and finding module 'Mylib::Parent'
use parent 'Mylib::Parent';

sub new { 
    my $class = shift;
    my $self = Mylib::Parent->new( shift, shift );
    bless $self, $class;
}

1;

<强> /perldir/use_child_three.pl

use Scalar::Util ('blessed');

use Secondlib::ChildThree;

my $obj = new Secondlib::ChildThree('Jack', 'Sparrow');
print "\n Class: ", blessed ( $obj );
print "\n ",$obj->{_first},' ',$obj->{_last};
print "\n ",$obj->getFirstName();

1;

答案 2 :(得分:0)

默认情况下,不应在普通的Perl脚本中使用packagepackage声明用于创建新的名称空间,以防止模块之间发生命名冲突。

为简单起见,您不必创建用于定义包的模块目录。事实上,在面向对象的Perl中,如果不打算在其他程序之间共享,那么在主程序中定义类的情况并不少见。

这是一个简单的继承示例。我创建了两个对象$wife是一个类Person,而$me是一个名为Developer的Person的子类。请注意,我没有newname 子例程 ..我的意思是.. 方法 在我的定义中Developer课程。那些由我的use parent -norequire qw(Person);声明继承。

#! /usr/bin/env perl

use strict;
use warnings;
use feature qw(say);
use Data::Dumper;

my $wife  = Person->new();
$wife->name("Susan");
$wife->occupation("Quantum Physicist");

say "Name: " . $wife->name;
say "Occupation: " . $wife->occupation . "\n";

my $me = Developer->new("Bob");
$me->programming_language("Perl");

say "Name: " . $me->name;
say "Language: " . $me->programming_language;

########################################################################
########################################################################

package Person;

sub new {
    my $class           = shift;
    my $name            = shift;
    my $occupation      = shift;

    my $self = {};
    bless $self, $class;

    $self->name($name);
    $self->occupation($occupation);
    return $self;
}

sub name {
    my $self            = shift;
    my $name            = shift;

    if ( defined $name ) {
        $self->{NAME} = $name;
    }
    return $self->{NAME};
}

sub occupation {
    my $self            = shift;
    my $occupation      = shift;
    if ( defined $occupation ) {
        $self->{OCCUPATION} = $occupation;
    }
    return $self->{OCCUPATION};
}

package Developer;
use parent -norequire, qw(Person);

sub programming_language {
    my $self            = shift;
    my $language        = shift;

    if ( defined $language ) {
        $self->{LANGUAGE} = $language;
    }

    return $self->{LANGUAGE};
}

可以使用SUPER类强制子类使用超类定义:

我本可以定义一个new 子程序,......呃... 方法,...不,呃... 我的Developer类中的构造函数

package Developer;

...

sub new {
    my $class           = shift;
    my $name            = shift;
    my $language        = shift;
    my $occupation      = "Code Slinger";

    my $self = {};
    bless $self, $class;       # Defines a Developer or subclass object

    $self->SUPER::name($name); # Sets the name of my Developer
    $self->SUPER::occupation($occupation); # We know the occupation
    return $self;
}

现在,如果我请求$me->occupation,它将返回Code Slinger