调用模块方法时传递的模块引用

时间:2018-07-13 19:41:06

标签: 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->get_header("foo"));
print_and_log("blah");

sub print_and_log
{
    my $message = shift;
    print("$message\n");
}

预期输出:

===== foo =====
blah

实际输出:

===== My_Util =====
blah

编辑:已修复语法错误

3 个答案:

答案 0 :(得分:10)

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

所以,假设我们有

package MyUtil;
sub foo {}

某个地方,电话

MyUtil->foo(1, 2, 3)

最终会做MyUtil::foo("MyUtil", 1, 2, 3)

你当然可以打电话

MyUtil::foo(1, 2, 3)

直接而不传递任何隐式参数。

另请参阅perldoc perlobj

另一个区别是::版本执行普通的函数调用,而->版本执行方法调用,该方法调用也遵循继承,即使用MyUtil->foo时不需要如果MyUtil::foo继承自提供MyUtil方法的类,则foo子元素。

答案 1 :(得分:3)

问题在于,使用语法MyUtil->get_header()时,您正在将get_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');

答案 2 :(得分:0)

问题是对My_Util->get_header()的调用隐式地将对My_Util的引用传递给get_header(),这没有考虑。

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