require
(参考)
http://clouder.jp/yoshiki/mt/archives/000184.html
以下のようなモジュールがあるとします、
./Foo/Bar/Baz.pm
package Foo::Bar::Baz;
use strict;
use warnings;
sub import {
print "Foo::Bar::Baz::import\n";
}
1;
クラス名を動的に作成してuseさせるには、
my $module = 'Baz';
my $class = "Foo::Bar::$module";
eval qq(use $class);
とするか、
my $module = 'Baz';
my $class = "Foo::Bar::$module";
eval qq(require $class; import $class);
とします。すると、
Foo::Bar::Baz::import
と、表示されます。しかし、
#eval qq(require $class; import $class);
eval {require $class; import $class;};
print $@;
とすると、
Can't locate Foo::Bar::Baz in @INC...
と$@にFoo::Bar::Bazが見つからんぞ(#゚Д゚)ゴルァ!!エラーがセットされています。
確かに、
my $module = 'Baz';
my $class = "Foo::Bar::$module";
require $class
だとエラーになります。でも、
require Foo::Bar::Baz
だとエラーになりません。
perldoc -f requireを再確認。
If EXPR is a bareword, the require assumes a ".pm" extension and
replaces "::" with "/" in the filename for you, to make it easy to load
standard modules. This form of loading of modules does not risk alter-
ing your namespace.
だそうです。なので、
my $module = 'Baz';
my $class = "Foo/Bar/$module.pm";
require $class
こうするとrequireされます。
☆☆requireのまとめ☆☆
barewordの場合、
require Foo::Bar::Baz;
Foo/Bar/Baz.pmがrequireされます。
barewordで無い場合
require "Foo/Bar/Baz.pm";
このように指定することでFoo/Bar/Baz.pmがrequireされます。
require "Foo::Bar::Baz";
もしくは
my $class = 'Foo::Bar::Baz';
require $class;
ではエラーになります。
The require function will look for the "Foo::Bar" file in the @INC array
and will complain about not finding "Foo::Bar" there.
と説明されています。このアタリちゃんと理解してませんでした。
my $class = 'Foo::Bar::Baz';
eval qq(require $class);
が、なぜ動くかと言うと、$classが展開されbarewordになった形でrequireされるからです。
例えば、
my $class = 'Foo::Bar::Baz';
eval qq(open(DH ,">>./tete.log"); print DH $class; close(DH); require $class);
print $@;
こんな感じで$classを出力しようとすると、
Bareword "Foo::Bar::Baz" not allowed while "strict subs" in use at (eval 1) line 1.
こんな感じでエラーになります。Barewordになってるんですねぇ。
eval-blockにすると、
my $class = 'Foo::Bar::Baz';
eval {open(DH ,">>./tete.log"); print DH $class; close(DH); require $class};
print $@;
エラーになります。
Can't locate Foo::Bar::Baz in @INC...
eval-blockの場合
open(DH ,">>./tete.log"); print DH $class; close(DH); require $class
の部分をPerlの構文として処理する為、$classがBarewordになりませぬ。
だからエラーになるのですね。
間違ってたら突っ込みお願いします。m(_ _)m
今回これを調べようと思ったのはUNIVERSAL::requireの翻訳やってたからでした。