我需要定义一些模块并在同一个文件中使用它们.不,我不能改变要求.
我想做类似以下的事情:
{
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();
Run Code Online (Sandbox Code Playgroud)
但是,这会产生以下消息:
无法在@INC中找到FooObj.pm ...
BEGIN失败了......
我如何让它工作?
bri*_*foy 14
除非我试图创建一个没有人应该知道的私有包,否则我会为每个文件放一个包.这解决了这个问题.但是,让我们把它们放在同一个文件中.
该用法加载文件并调用该import包中的方法.真的只是它的论证看起来像一个模块名称.它正在寻找文件.如果文件不存在,那就是barfs.
你可以这样做,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;
Run Code Online (Sandbox Code Playgroud)
如果你需要与一个包进行交互(这就是它的全部内容:不是模块或对象),你只需要在想要使用它之前定义它.如果您需要导入某些内容,可以import直接调用:
FooObj->import( ... );
Run Code Online (Sandbox Code Playgroud)
假设有一些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;
Run Code Online (Sandbox Code Playgroud)
spa*_*azm 10
按照惯例,我们将一个包放在一个文件中,并将它们命名为相同的东西,但这只是为了方便.您可以将多个包放在一个文件中.由于它们已经加载,因此您无需使用use.
您也不需要为包创建特殊的作用域,因为package关键字会处理它.使用大括号确实有助于our变量的范围.所以你并不严格需要那些支撑块,但它们是个好主意.
use使用包命名约定来查找要加载的相应文件.该package模块内部关键字定义的命名空间.导入函数处理包加载(通常从Exporter继承).
#!/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
Run Code Online (Sandbox Code Playgroud)