0
#! /usr/bin/perl

# this is the object tester

{package Hate;
sub status {
my $class = shift;
print "-- $_[0] $_[1] $_[2]\n";
print "$class exists and ", $class->stats($_[0]), "and ", $class->type($_[1]), "and ",     $class->location($_[2]);
}
}

{package Grudge;
@ISA = "Hate";
sub stats{"$_[0]\n"}
sub type{"$_[0]\n"}
sub location{"$_[0]\n"}
}

Hate::status("Grudge", @ARGV);

我跑了 ./program 一二三

这个输出是我预期的怨恨存在,一二三

这就是我得到的怨恨存在和怨恨和怨恨和怨恨

但是当我使用这个脚本时

#! /usr/bin/perl

# this is the object tester

{package Hate;
sub status {
my $class = shift;
print "-- $_[0] $_[1] $_[2]\n";
print "$class exists and ", $class->stats($_[0]), "and ", $class->type($_[1]), "and ",     $class->location($_[2]);
}
}

{package Grudge;
@ISA = "Hate";
sub stats{"$_[1]\n"}
sub type{"$_[1]\n"}
sub location{"$_[1]\n"}
}

Hate::status("Grudge", @ARGV);

这行得通。

4

1 回答 1

4

在您的第一个示例中,$class->stats($_[0])作为方法调用并作为第一个参数传递一个对象,需要像在Hate::status. 这就是$_[1]有效的原因:因为该方法的第一个参数实际上是@_(after $self) 中的第二项。

@_如果您在函数的开头解包参数,事情会变得更加清晰和易于管理,例如

{
    package Hate;
    sub status {
        my ($class, $stats, $type, $location) = @_;
        print "-- $stats $type $location\n";
        print "$class exists and ", $class->stats($stats), ...;
    }
}

{
    package Grudge;
    our @ISA = qw(Hate);
    sub stats { my ($self, $stats) = @_; $stats; }
    sub type { my ($self, $type) = @_; $type; }
    sub location { my ($self, $location) = @_; $location; }
}

Hate::status('Grudge', @ARGV);

附带说明一下,您对对象的使用并不典型——如果您提供更多代码,我们也许能够提供更惯用的 Perl 解决方案。例如,您的所有对象都没有构造函数,而目前这三个 Grudge 方法似乎在做同样的事情。也不清楚为什么GrudgeHate(如 所示@ISA)的子类。

如果您真的不想Grudge将其自己的名称作为参数传递,您可以将其方法作为函数调用,&{$class . '::stats'}()但您必须禁用strict subs. 通常最好像现在这样调用方法。

于 2012-07-01T17:37:13.663 回答