Perl 在对模块方法的调用中传递的模块引用

Perl 在对模块方法的调用中传递的模块引用,perl,Perl,我有一个名为fetch.pl的perl脚本和一个名为My_Util.pm的模块 My_Util.pm package My_Util; sub get_header { my $msg = shift; return " ===== $msg ===== "; } 1; # Perl modules must return a true value when loaded. fetch.pl use My_Util; print_and_log(My_Util->g

我有一个名为
fetch.pl
的perl脚本和一个名为
My_Util.pm
的模块

My_Util.pm

package My_Util;

sub get_header
{
    my $msg = shift;
    return " ===== $msg ===== ";
}

1; # Perl modules must return a true value when loaded.
fetch.pl

use My_Util;

print_and_log(My_Util->get_header("foo"));
print_and_log("blah");

sub print_and_log
{
    my $message = shift;
    print("$message\n");
}
预期输出:

===== foo =====
blah
===== My_Util =====
blah
实际输出:

===== foo =====
blah
===== My_Util =====
blah

编辑:修复了语法错误

问题是对
My\u Util->get\u header()
的调用隐式地将对
My\u Util
的引用传递到
get\u header()
,而该引用未被考虑

sub get_header
{
    my $self = shift;
    my $msg = shift;
    return " ===== $msg ===== ";
}

->get_header
语法用于方法调用。方法调用将invocant(即对象或类名)作为隐式第一个参数传递

所以,假设我们有

package MyUtil;
sub foo {}
在某处,电话

MyUtil->foo(1, 2, 3)
最后执行
MyUtil::foo(“MyUtil”,1,2,3)

你当然可以打电话

MyUtil::foo(1, 2, 3)
直接传递而不传递任何隐式参数

另见


另一个区别是
版本执行普通函数调用,而
->
版本执行方法调用,方法调用也遵循继承,也就是说,如果
MyUtil
从提供
foo
方法的类继承,那么使用
MyUtil->foo
时根本不需要
MyUtil::foo
子类。

问题是,使用语法
MyUtil->get\u header()
,您将调用
get\u header()
。该调用被转换为
MyUtil::get_handler('MyUtil','foo')
,您需要考虑传递给子例程的额外参数

sub get_header {
  my $class = shift; # Get class name
  my ($msg) = @_;    # Get message

  return " ===== $msg ===== ";
}
如果您不打算将
get_header()
作为类方法,那么不要将其作为类方法调用。如果将其称为
MyUtil::get_header('foo')
,那么现有模块代码将正常工作

或者,您可以将子例程从模块“导出”到调用包中。您可以通过在包中添加以下两行来完成此操作:

use Exporter;
our @EXPORT = qw[get_header];
然后,在主程序中,您将能够调用导出的子例程,而无需提及其包名

get_header('foo');

使用My_Util.pm
是语法错误。您的
MyUtil.pm
文件缺少
声明和返回值。您的
myu Util.pm
是否是类?问题是,您显示的代码无法运行,因此不清楚到底发生了什么。修复了语法错误(包声明、导入和返回代码)
My_Util.pm
是一个帮助程序的集合。如果该包不是一个类,我建议不要使用
->
从中调用subs,而是
My_Util::func
(或者导出模块中的名称
func
,如果希望能够使用非限定名称,则将其导入调用方)。在
My\u Util->get\u header()
中没有传递引用。方法接收的第一个参数是包含“My\u Util”的字符串。它通常存储在名为
$class
的变量中,而不是
$self
的变量中。