代码之家  ›  专栏  ›  技术社区  ›  Robert S. Barnes Antoni

如何调用在同一文件中定义的Perl包?

  •  16
  • Robert S. Barnes Antoni  · 技术社区  · 15 年前

    我需要定义一些模块并在同一个文件中使用它们。不,我不能改变要求。

    我想做如下事情:

    {
        package FooObj;
    
        sub new { ... }
    
        sub add_data { ... }
    }
    
    {
        package BarObj;
    
        use FooObj;
    
        sub new { 
            ... 
            # BarObj "has a" FooObj
            my $self = ( myFoo => FooObj->new() );
            ...
        }
    
        sub some_method { ... }
    }
    
    my $bar = BarObj->new();
    

    但是,这会导致消息:

    在@inc中找不到fooobj.pm…
    开始失败…

    我怎样才能让它工作?

    3 回复  |  直到 7 年前
        1
  •  23
  •   Dave Sherohman    9 年前

    放弃 use . 说真的。

    使用 告诉perl从另一个文件读入代码,因为代码在同一个文件中,所以不需要这样做。

        2
  •  14
  •   brian d foy    8 年前

    除非我试图创建一个没有人知道的私有包,否则我会为每个文件放置一个包。这就解决了问题。但是,让我们把它们放在同一个文件里。

    这个 use 加载文件并调用 import 方法。只是顺便说一下,它的参数看起来像一个模块名。它在找文件。如果文件不在那里,它就会出现问题。

    你可以这样做,在哪里 BarObj 假定 FooObj 已经存在:

    {
        package FooObj;
        sub new      { bless { _count => 0 }, $_[0] }
        sub add_data { $_[0]->{_count}++ }
    }
    
    {
        package BarObj;
        use Data::Dumper;
    
        sub new {
            bless { myFoo => FooObj->new }, $_[0];
            }
    
        sub foo         { $_[0]->{myFoo} }
        sub some_method { print Dumper( $_[0] ) }
    }
    
    my $bar = BarObj->new;
    $bar->some_method;
    

    如果需要与包交互(仅此而已:不是模块或对象),只需在使用它之前定义它。如果需要导入某些内容,可以调用 进口 直接:

    FooObj->import( ... );
    

    假设有来自 足客 你想导入(但不是继承!)你打电话 进口 直接无负荷;

    {
        package FooObj;
        use Data::Dumper;
        sub new      { bless { _count => 0 }, $_[0] }
        sub add_data { $_[0]->{_count}++ }
    
        use Exporter qw(import);
        our @EXPORT = qw(dumper);
        sub dumper   { print Dumper( $_[0] ) }
    }
    
    {
        package BarObj;
        FooObj->import;
    
        sub new {
            bless { myFoo => FooObj->new }, $_[0];
            }
    
        sub foo         { $_[0]->{myFoo} }
    
        # dumper mixin, not inherited.
        sub some_method { dumper( $_[0] ) }
    }
    
    my $bar = BarObj->new;
    $bar->some_method;
    
        3
  •  10
  •   spazm    8 年前

    按照惯例,我们将一个包放在一个文件中,并将它们命名为相同的东西,但这只是为了方便。您可以将多个包放在一个文件中。因为它们已经加载,所以不需要使用 use .

    您也不需要为包创建特殊的作用域,因为package关键字会处理这个问题。使用大括号有助于确定 our 变量。所以你不需要那些支撑块,但它们是个好主意。

    使用 使用包命名约定查找要加载的适当文件。这个 package 模块内的关键字定义命名空间。导入函数处理包加载(通常从导出器继承)。

    #!/usr/bin/perl
    
    use strict;
    use warnings;
    
    package FooObj;
    
    sub new
    {
            my $this  = shift;
            my $class = ref($this) || $this;
            my $self  = {};
            bless $self, $class;
            $self->initialize();
            return $self;
    }
    
    sub initialize { }
    sub add_data   { }
    
    package BarObj;
    
    #use FooObj; <-- not needed.
    
    sub new
    {
            my $this  = shift;
            my $class = ref($this) || $this;
            my $self  = { myFoo => FooObj->new() };
            bless $self, $class;
            $self->initialize();
            return $self;
    }
    sub initialize  { }
    sub some_method { }
    sub myFoo       { return $_[0]->{myFoo} }
    
    package main;
    use Test::More;
    my $bar = BarObj->new();
    isa_ok( $bar,        'BarObj', "bar is a BarObj" );
    isa_ok( $bar->myFoo, 'FooObj', "bar->myFoo is a FooObj" );
    done_testing();
    
    __DATA__
    
    ok 1 - bar is a BarObj isa BarObj
    ok 2 - bar->myFoo is a FooObj isa FooObj
    1..2