以下脚本p.pl工作正常:
use feature qw(say);
use strict;
use warnings;
use lib '.';
use P1;
my $obj = P1->new(name => 'John');
say "The name is: ", $obj->name;
Run Code Online (Sandbox Code Playgroud)
P1在文件中定义类的位置P1.pm:
package P1;
use Moose;
has name => (is => 'rw', isa => 'Str');
1;
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试将类移动P1.pm到主脚本中时:
#! /usr/bin/env perl
use feature qw(say);
use strict;
use warnings;
my $obj = P1->new(name => 'John');
say "The name is: ", $obj->name;
package P1;
use Moose;
has name => (is => 'rw', isa => 'Str');
Run Code Online (Sandbox Code Playgroud)
我收到错误:
Can't locate object method "name" via package "P1" at ./p.pl line 8.
Run Code Online (Sandbox Code Playgroud)
您正在尝试在执行调用之前使用该属性来has创建它.
内联模块的一种相对简单的方法如下:
use feature qw(say);
use strict;
use warnings;
use FindBin qw( $RealBin );
use lib $RealBin;
BEGIN {
package P1;
use Moose;
has name => (is => 'rw', isa => 'Str');
$INC{"P1.pm"} = 1;
}
use P1;
my $obj = P1->new(name => 'John');
say "The name is: ", $obj->name;
Run Code Online (Sandbox Code Playgroud)
请记住,它仍然不完全相同.例如,模块现在位于脚本中的三个pragma范围内.也许你应该使用App :: FatPacker或类似的.
has它只是一个在运行时执行的常规函数调用,所以直到你的运行后它才会运行say.
通常你是use一个Moose类,并且use Class;只是简称BEGIN { require Class; ... },因此通常,所有Moose函数has都将在执行useing 的脚本的编译期间执行.另请参阅perlmod中的"BEGIN,UNITCHECK,CHECK,INIT和END".
虽然我认为这不是最好的解决方案,但您可以将package P1;声明粘贴在一个BEGIN { ... }块中.或者,您可以package P1在主代码之前放置(在它自己的块中最好,因此它有自己的范围).
但是,首先要将类放在同一个文件中也有一些说法,例如参见In Perl中的答案,如何将多个类放在单个.pm文件中.