两个主要错误,都是使用use strict; use warnings;
. 总是这样做。(您在模块中使用了它,但没有在脚本中使用它。)
您在一个地方正确使用,但不久之后$ba::base_addr
您继续使用不存在的变量。$base_addr
您只能$ba::base_addr
像$base_addr
当前包一样访问ba
,或者如果您为其创建一个名为$base_addr
.
您要么需要$ba::base_addr
一致地使用,要么需要将变量导出到使用模块。(这是我提到的别名的一种方式。)
$ba::base_addr
你从不给and赋值$oa::offset_addr
,所以当你试图添加它们(“非数字”)和试图打印它们(“未初始化”)时,Perl 会给你警告。
我们将同时解决的其他一些问题:
一个模块必须返回一个真值,也就是说,最后一个计算的表达式必须计算为真。因此,以模块结尾是标准的1;
(这也适用do
于可靠的错误检测:do $qfn or die $@ || $!;
.)
您应该使用require
而不是do
因为文件有package
声明。.pm
如果您将它们重命名为并使用,那就更好了use
。
模块的名称应该与它的包声明相匹配。如果它包含package ba;
,则该文件应命名为ba.pm
.
#!
仅在以下情况下才有意义:1)它们是文件的前两个字符,以及 2)如果文件被提供给操作系统执行。您的模块都不是这种情况。
ba.pm
:
package ba;
use strict;
use warnings;
our $base_addr = 123;
1;
oa.pm
:
package oa;
use strict;
use warnings;
our $offset_addr = 456;
1;
script.pl
:
#!/usr/bin/perl
use strict;
use warnings;
use ba qw( );
use oa qw( );
my $final_val = $ba::base_addr + $oa::offset_addr;
print "base_addr = $ba::base_addr\n";
print "offset_addr = $oa::offset_addr\n";
print "final addr = $final_val\n";
如果您导出变量,您可以避免在任何地方说出包名称,前面提到过。
ba.pm
:
package ba;
use strict;
use warnings;
use Exporter qw( import );
our @EXPORT_OK = qw( $base_addr );
our $base_addr = 123;
1;
oa.pm
:
package oa;
use strict;
use warnings;
use Exporter qw( import );
our @EXPORT_OK = qw( $offset_addr );
our $offset_addr = 456;
1;
script.pl
:
#!/usr/bin/perl
use strict;
use warnings;
use ba qw( $base_addr );
use oa qw( $offset_addr );
my $final_val = $base_addr + $offset_addr;
print "base_addr = $base_addr\n";
print "offset_addr = $offset_addr\n";
print "final addr = $final_val\n";
但是,导出变量通常是不好的形式。创建访问器通常要好得多。
ba.pm
:
package ba;
use strict;
use warnings;
use Exporter qw( import );
our @EXPORT_OK = qw( base_addr );
my $base_addr = 123;
sub base_addr { $base_addr }
1;
oa.pm
:
package oa;
use strict;
use warnings;
use Exporter qw( import );
our @EXPORT_OK = qw( offset_addr );
my $offset_addr = 456;
sub base_addr { $base_addr }
1;
script.pl
:
#!/usr/bin/perl
use strict;
use warnings;
use ba qw( base_addr );
use oa qw( offset_addr );
my $final_val = base_addr() + offset_addr();
print "base_addr = ".base_addr()."\n";
print "offset_addr = ".offset_addr()."\n";
print "final addr = $final_val\n";