这应该是相当微不足道的,但我无法自己解决这个问题。
有了下面的代码,有没有办法摆脱dirname(rel2abs($0))
的许多调用?
package Foo;
use File::Basename;
use File::Spec::Functions qw/rel2abs/;
use Carp qw/croak/;
use 5.010;
use constant BAR_NAMES => {
WATER => dirname(rel2abs($0)) . '/../data/water.png',
FIRE => dirname(rel2abs($0)) .'/../data/fire.png',
GRASS => dirname(rel2abs($0)) .'/../data/grass.png'#,
#and so on
};
sub get {
my ($self, $name) = (shift, shift);
if (exists BAR_NAMES->{$name}) {
#return some calculated data based on $name value
} else {
croak("Constant `$name` is not declared.");
}
};
1;
谢谢。
答案 0 :(得分:6)
您可以在map
:
use constant BAR_NAMES =>
{
map { uc( $_ ) => dirname(rel2abs($0)) . "/../data/$_.png" }
qw< water fire grass >
};
如果我没弄错的话,dirname
不一定是必要的:
use constant BAR_NAMES =>
{
map { uc( $_ ) => rel2abs("$0/../data/$_.png") }
qw< water fire grass >
};
答案 1 :(得分:5)
除了现有的答案之外,还有
use constant PROJ_ROOT => dirname(rel2abs($0)) . '/..';
use constant BAR_NAMES => {
WATER => PROJ_ROOT.'/data/water.png',
FIRE => PROJ_ROOT.'/data/fire.png',
GRASS => PROJ_ROOT.'/data/grass.png',
};
和
use FindBin qw( $RealBin );
use constant BAR_NAMES => {
WATER => "$RealBin/../data/water.png",
FIRE => "$RealBin/../data/fire.png",
GRASS => "$RealBin/../data/grass.png",
};
答案 2 :(得分:3)
my $dirname;
BEGIN { $dirname = dirname(rel2abs($0)); }
use constant BAR_NAMES => {
WATER => $dirname . '/../data/water.png',
FIRE => $dirname .'/../data/fire.png',
GRASS => $dirname .'/../data/grass.png'#,
#and so on
};
您需要一个BEGIN
块,因为use
语句中的任何表达式都是在编译时计算的。
答案 3 :(得分:3)
use constant BAR_NAMES => do {
my $dirname = dirname(rel2abs($0));
{
WATER => $dirname . '/../data/water.png',
FIRE => $dirname .'/../data/fire.png',
GRASS => $dirname .'/../data/grass.png'#,
#and so on
}
};