2017-12-19 34 views
0

私は下のコードではsub2の "未定義のサブルーチン"を取得していますが、sub1ではありません。私が手try.pl私が実行するとPerlでは、perlモジュールで "undefined subroutine"を取得するのはなぜですか?メインではないのですか?

これは...これはtry_common.pmです...

#! /usr/bin/env perl 

use strict; 
use IO::CaptureOutput qw(capture_exec_combined); 

package try_common; 

use Exporter; 
our @ISA = qw(Exporter); 
our @EXPORT = qw(
    sub2 
); 

sub sub2 { 

    (my $cmd) = @_; 

    print "Executing... \"${cmd}\"\n"; 
    my ($stdouterr, $success, $exit_code) = capture_exec_combined($cmd); 
    print "${stdouterr}\n"; 

    return; 
} 

1; 

#!/usr/bin/env perl 

use strict; 
use IO::CaptureOutput qw(capture_exec_combined); 

use FindBin qw($Bin); 
use lib "$Bin"; 
use try_common; 

print "Running try.pl\n"; 
sub1("echo \"in sub1\""); 
sub2("echo \"in sub2\""); 

exit; 

sub sub1 { 

(my $cmd) = @_; 

print "Executing... \"${cmd}\"\n"; 
my ($stdouterr, $success, $exit_code) = capture_exec_combined($cmd); 
print "${stdouterr}\n"; 

return; 
} 

のperlスクリプト(try.pl)です...

% ./try.pl 
Running try.pl 
Executing... "echo "in sub1"" 
in sub1 

Executing... "echo "in sub2"" 
Undefined subroutine &try_common::capture_exec_combined called at 
/home/me/PERL/try_common.pm line 20. 

私がカットした場合/貼り付けるので、これは問題のスコープのいくつかの種類のように見える "使用IO :: CaptureOutput QW(capture_exec_combined);" sub2の最初の行として動作します。 try.pl(これはsub1 OKを実行します)では必要ありませんが、perlモジュールの問題です。うーん....

ありがとうございました!

+2

それは.PMファイルにシェバング( '#'!)の行を追加しても意味がありません。 – ikegami

答えて

5

あなたは、パッケージを宣言する前use句によってcapture_exec_combinedを輸入し、それをmainパッケージ、ないtry_commonにインポートされました。パッケージ宣言をさらに上に移動します。

+0

Hmmmm ...すべてのものをメインスペースに入れるための1つの方法は、 "package"ステートメントを完全に省略することでしょうか?私は、このperlモジュールのものを使うつもりの2つのメインスクリプトを持っています。私は、 "package"ステートメントの使用が何であるか疑問に思っています。 – daveg

+4

'package'ステートメントを省略すると、長期的には解決するよりも多くの問題が発生します。適切なPerlモジュールを書く方法を学んでください([perlmod](http://p3rl.org/perlmod)参照)。 – choroba

+1

@daveg複数のファイルを使用しているのと同じ理由で、無関係なものを分離するためです。この分離により、モジュールは同じ名前のサブシステムを持つことができます。プログラムが使用する可能性がある他のモジュールとモジュールが同じでないことを保証する方法はありません。 ///これにより、プログラムは複数のクラスを持つことができます。 – ikegami

-1

私はそれを理解したと思います。もし、perlモジュールで "capture_exec_combined"に "::"と接頭辞が付いていれば動作します。

まだ、try.plのメインでは必要ないのはなぜですか?

+1

これはコメントではありません – ssr1012

4

モジュールの仕組みを理解するには、perlmodのドキュメントをご覧ください。要するに:あなたはpackage A(Perl 5の中で)使用する場合

  1. は、あなたがAに次のコードの名前空間を変更し、その時点の後にすべてのグローバルシンボル(例えばサブルーチン)の定義は、そのパッケージになります。スコープ内のサブルーチンは、にエクスポートする必要はなく、スコープ名の前に使用することができます(A::function)。これはあなたが見つけたようです。

  2. Perlは、モジュールモジュールと分割コードを異なるファイルで作成する方法として、またそのオブジェクト指向機能の基礎としても使用します。

  3. ほとんどの場合、モジュールは、Exporterと呼ばれる特別なコアモジュールによって処理されます。 Exporterを参照してください。このモジュールでは、@EXPORT,@EXPORT_OK@ISAなど、何をするかを知るためにいくつかの変数を使用しています。最初に、のモジュールが含まれ、use Moduleのモジュールが含まれている場合、デフォルトでエクスポートする名前を定義します。 2番目にエクスポートされる名前が定義されています(ただし、use Module qw(name1 name2)で説明する必要があります)最後に、オブジェクト指向の方法でモジュールであることがわかります。オブジェクトの向きを気にしない場合、あなたはモジュールを定義するときExporter

また、他の回答で述べたように、package module宣言は、それはそのスコープの下になります後は何もしてファイルにするために最初のものでなければなりません。

+0

この詳細な説明をありがとう。私は切り捨てて今メモに貼り付けています:-) – daveg

+0

確かに、リンクも見てください。これは簡単な要約です。 –

0

私はこの間違いを犯すと嫌ですが、それ以上はそれほど気にしません。あなたが開発できる2つの習慣があります:

ほとんどの場合、ファイル全体をパッケージにします。最初の行はpackageステートメントになり、その他のpackageステートメントはファイルに表示されません。

新しいPACKAGE BLOCK構文を使用して、そのパッケージのすべてをブロック内に配置します。私はローカルでのみ必要な場合があります少人数のクラスのためにこれを行う:

package Foo { 
    # everything including use statements go in this block 
    } 
関連する問題