dポイントプレゼントキャンペーン実施中!

エラーでハマっている為、use AutoLoaderする際の記述法と概念を知りたいです。
-----------------------------------------------
test.cgi


use lib '/var/www/lib';
unshift @INC, '/var/www/lib';
use AutoLoader 'AUTOLOAD';

RegistDataList();#ここで存在しない関数を呼び出す
-----------------------------------------------

●自作モジュール(UserEditCommon.pm)
-----------------------------------------------
package UserEditCommon;
BEGIN{
use Exporter();
@ISA = qw(Exporter);
@EXPORT_OK = qw(RegistDataList);
}
use utf8;
use open ":utf8";
use open ":std";
use AutoLoader 'AUTOLOAD';
1;
__END__
ここ以降に色々な関数が記述されていますが、元々ライブラリーだった為、OOP的なコンストラクタやデストラクタは記述していません。
----------------------------------------------

$ perl -e 'use AutoSplit; autosplit($ARGV[0], $ARGV[1], 0, , 1)' UserEditCommon.pm auto
上記を実行すると、auto/UserEditCommon/関数名.alファイルが沢山出来ました。
それを/var/www/lib/autoとしてUP

●下記を参考にしているのですが
http://perldoc.jp/docs/perl/5.8.0/AutoLoader.pod …
抜粋「B<AutoLoader>のAUTOLOADサブルーチンために、
明示的にそれをインポートI<しなければなりません>。」
とある為、
use AutoLoader 'AUTOLOAD';
と記述する際はtest.cgi内ではsub AUTOLOADが必要ないと解釈しています。

実行した際、
Can't locate auto/main/RegistDataL.al in @INC (@INC contains: /var/www/lib ...
となり、auto/main/のRegistDataList.alが呼ばれているはずなのに、なぜRegistDataL.alという名前でのエラーなのでしょうか

●またtest.cgi内で
use AutoLoader;
とした場合のsub AUTOLOAD内の記述をお教え願えませんでしょうか

sub AUTOLOAD {
#print "$AUTOLOAD は未定義です";
my $sub = $AUTOLOAD;
$sub =~ s/.*:://;
$AutoLoader::AUTOLOAD = $sub;
goto &AutoLoader::AUTOLOAD;
}

上記のようにしても、エラー内容が
Can't locate auto/AutoLoader/RegistDataL.al in @INC (@INC contains: /var/...
となってしまい、どうすればよいか途方にくれています。

A 回答 (3件)

違いますよ。

Exporter は 別モジュールで定義されている関数を、
"モジュール名::関数()" ではなくて、"関数()" で呼び出すために使っています。

-- Bar.pm
package Bar;
use strict;
use warnings;
use base qw(Exporter);

our @EXPORT_OK = qw(function1 function2);

sub function1 { print "call function1. EXPORT_OK\n"; }
sub function2 { print "call function2. EXPORT_OK\n"; }
sub function3 { print "call function3. No EXPORT\n"; }

1;

-- test.pl
use strict;
use warnings;
use lib './';
use Bar qw(function1); # Bar::function1をインポートする

function1(); # call function1. EXPORT_OK
# function2(); # これはできない
Bar::function2(); # call function2. EXPORT_OK

# function3(); # これはできない
Bar::function3();# call function3. No EXPORT
    • good
    • 0
この回答へのお礼

use AutoLoader 'AUTOLOAD';を使った例と使わない例とで
分かりやすく事例をご教授頂きありがとうございます。

また、その後の調べで
use base qw(Exporter);

use Exporter; our @ISA = qw(Exporter);
と等価な事も勉強になりました。

Exporterは、直接"関数()" で呼び出し可能になるんですね。

また
our @EXPORT_OK = qw(function1 function2);
としていても、
呼び出し元で
use Bar qw(function1);
としていた場合は、
function2(); # これはできない
というのも理解出来ました。

@EXPORTや@EXPORT_OKにエクスポートしたいシンボルのリストが入っていなくても、
パッケージ名を付ければ、呼び出し可能という事も大変分かりやすい事例としてご教授頂いていた為、理解できました。
Bar::function3();#呼び出し可能

何度も読み直し調べ直し、理解するのに多少時間を要しましたが、この度は色々と分かり易いご解説、本当にありがとうございました。

お礼日時:2010/03/31 14:32

Foo.pm 内でAutoLoaderをuseしているので、test.pl では、FooだけuseすればOKです。

    • good
    • 0
この回答へのお礼

test.plで
our @EXPORT_OK = qw(function1);
している為、要求された時のみエクスポートする際、Foo.pmのAutoLoaderが効く形になるんですね。

なるほどですね~そうなんですか~~

色々ありがとうございます!!

お礼日時:2010/03/27 01:11

使用する関数をexportするか、モジュール名::関数 で呼び出す必要があると思います。



# Foo.pm
package Foo;
use strict;
use warnings;
use AutoLoader 'AUTOLOAD';

use base qw(Exporter);
our @EXPORT_OK = qw(function1);

1;
__END__

sub function1 {
print "Foo::function1. EXPORT OK function\n";
}

sub function2 {
print "Foo::function2. No EXPORT function\n";
}

# test.pl
use strict;
use warnings;
use lib './';
use Foo qw(function1);

function1();
Foo::function2();

$ perl -e 'use AutoSplit; autosplit($ARGV[0], $ARGV[1], 0, 1, 1)' Foo.pm ./auto
$ perl test.pl
Foo::function1. EXPORT OK function
Foo::function2. No EXPORT function
    • good
    • 0
この回答へのお礼

ourする必要があったんですね。
後、オートロードさせたいFoo.pmモジュールもUPする必要がある事と(必要ないのかな・・と思ってた事と文字化けに苦しみ、モジュール化とオートロード等この辺りが初めての取り組みでしたので、頭の中で整理できていませんでした)

ご教授頂いた
test.pl内で
use Foo qw(function1);
しておけば、無理に
test.pl内で
use AutoLoaderして自分で関数作る必要もなかったって事だったんですね。恐れ入ります。

メインのtest.plで
use AutoLoaderしないのは、
mod_perlの場合などでは何でもかんでもオートロードしてしまう為、よくないという話をどこかで拝見したのですが、その事につながる為って事なのでしょうか・・

もし、何かご助言頂けるようでしたらお願いしたいのですけれども
いずれにしても、お陰様で無事動かすことができました!

ありがとうございます

お礼日時:2010/03/26 22:50

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!