8

モジュールからサブルーチンを呼び出すとき、私はよく::混乱します。それがパスに関連して->いることと、モジュール/サブルーチンがオブジェクトに使用されている場所であることはわかっていますが、一見両方を交換できるように見えて、すぐにエラーが発生しない理由がよくわかりません。より大きなパッケージの一部である perl モジュールがあります。::->FullProgram::Part1

私はちょうどモジュールを把握しようとしていますが、Perl オブジェクトに関してはまだぐらついていますが、誤ってこれを行っていました:

FullProgram::Part1::subroutine1();

それ以外の

FullProgram::Part1->subroutine1();

そのため、ハッシュ ref を subroutine1 に渡し$class/$self、オブジェクト参照を処理するために使用して誤って使用しないように注意していたときに::、ハッシュ ref が消えたように見える理由を不思議に思ってしまいます。私は教訓を学びましたが、違いの説明が本当に欲しいです. これらに関する perldocs とさまざまな Web サイトを読みましたが、2 つの比較は見たことがありません (Google で検索するのは非常に困難です...)。

4

4 に答える 4

9

バニラサブとメソッドであるサブの間に固有の違いはありません。それはあなたがそれをどのように呼ぶかにかかっています。


Class::foo('a');

これは を呼び出しますClass::fooClass::foo存在しない場合、継承ツリーはチェックされません。Class::foo指定された引数 ( ) のみが渡されます'a'

以下とほぼ同じです。my $sub = \&Class::foo; $sub->('a');


Class->foo('a');

これは を呼び出すClass::fooか、存在しないfoo場合はその基本クラスの 1 つを呼び出します。Class::foo呼び出し元 ( の左側にあるもの->) が引数として渡されます。

以下とほぼ同じです。my $sub = Class->can('foo'); $sub->('Class', 'a');

于 2012-11-20T18:08:47.560 に答える
7
FullProgram::Part1::subroutine1();

空のパラメーター リストでsubroutine1パッケージのサブルーチンを呼び出します。FullProgram::Part1

FullProgram::Part1->subroutine1();

最初の引数としてパッケージ名を使用して同じサブルーチンを呼び出します (サブクラス化すると、少し複雑になることに注意してください)。この構文は、次のようなサブクラスのオブジェクトを構築するためにクラス名を必要とするコンストラクター メソッドによって使用されます。

sub new {
    my ($class, @args) = @_;
    ...
    return bless $thing, $class;
}

参考までに: Perl OOでは、パッケージ/クラス名ではなく、最初の引数としてオブジェクト (祝福された参照) を使用した$object->method(@args)呼び出しが表示されます。Class::methodこのようなメソッドでは、サブルーチンは次のように機能します。

sub method {
    my ($self, $foo, $bar) = @_;
    $self->do_something_with($bar);
    # ...
}

do_something_withこれは、最初の引数としてオブジェクトを使用してサブルーチンを呼び出し、その後にで$bar最初に渡した 2 番目のリスト要素の値が続きます。そうすれば、オブジェクト自体が失われることはありません。method@args

メソッドを呼び出すときに継承ツリーがどのように重要になるかについての詳細は、ikegami's answerを参照してください。

于 2012-11-20T18:08:37.797 に答える
5

両方を使う!

use Module::Two;

Module::Two::->class_method();

これは機能しますが、あいまいさからも保護することに注意してください。シンプル

Module::Two->class_method();

次のように解釈されます:

Module::Two()->class_method();

(モジュールでサブルーチンTwoを呼び出し、その戻り値でclass_methodを呼び出そうとすると、ランタイムエラーが発生したり、まったく異なるクラスでクラスまたはインスタンスメソッドが呼び出されたりする可能性があります)モジュールにサブ2がある場合は、次のようになります Moduleにあるのはコードのビジネスではないので、どちらかに依存するべきではありません。

于 2012-11-20T19:57:03.573 に答える
0

歴史的に、Perl には OO がありませんでした。そして、FullProgram::Part1::subroutine1();sytax で呼び出されるパッケージからの関数。または、構文を使用する前でもFullProgram'Part1'subroutine1();(非推奨)。

その後、符号付きの OOP を実装しまし->たが、実際にはあまり変更していません。FullProgram::Part1->subroutine1();を呼び出しsubroutine1FullProgram::Part1、第 1 パラメーターとして渡します。オブジェクトを作成するときに、これの使用法を確認できます: my $cgi = CGI->new(). これで、このオブジェクトからメソッドを呼び出すと、左側の部分も最初のパラメーターとして function: に渡されます$cgi->param('')paramそれが、彼が呼び出したオブジェクト (通常は という名前) を取得する方法$selfです。それでおしまい。->OOPのハックです。その結果、Perl にはクラス (パッケージはそれらとして機能します) はありませんが、オブジェクト (「オブジェクト」ハックも - それらは祝福されたスカラーです) があります。

my $cgi = new CGI;Offtop:構文で呼び出すこともできます。と同じCGI->newです。あなたが言うときも同じですprint STDOUT "text\n";。ええ、ただ電話するだけIOHandle::print()です。

于 2012-11-20T18:18:17.953 に答える