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);

私は./program1、2、3を実行しました

この出力は私が期待したものです恨みが存在し、1と2と3

これは私が恨みが存在し、恨みと恨みと恨みを持っているものです

ただし、このスクリプトを使用すると

#! /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])として呼び出され、最初の引数としてオブジェクトが渡されます。これは、で行ったようにシフトする必要があります。これが機能する理由です。メソッドの最初の引数は、実際には(after ) の 2 番目の項目であるためです。Hate::status$_[1]@_$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 ソリューションを提供できる可能性があります。たとえば、どのオブジェクトにもコンストラクターがなく、現時点では 3 つの Grudge メソッドが同じことをしているように見えます。が( で示されているように)Grudgeのサブクラスである理由も明確ではありません。Hate@ISA

Grudge引数として独自の名前を渡されたくない場合は、メソッドを関数として呼び出すことができ&{$class . '::stats'}()ますが、無効にする必要がありますstrict subs。通常、現在行っているようにメソッドを呼び出す方が適切です。

于 2012-07-01T17:37:13.663 に答える