Модуль Perl знает, где он установлен? - PullRequest
7 голосов
/ 13 апреля 2009

Я начал создавать пакет Perl, который содержит шаблон электронной почты по умолчанию.

Манифест выглядит примерно так:

SendMyEmail.pm
SendMyEmail/defualt_email.tt

В настоящее время я знаю, где находится модуль (и шаблон), но знает ли сам модуль, где он находится на диске? Так может ли модуль найти шаблон по умолчанию без моей помощи?

# This is what I would like to do.
package SendMyEmail;
sub new {
    my ($self, $template) = @_;
    $template ||= $dir_of_SendMyEmail .'/SendMyEmail/default_email.tt'; # ??
}

Есть ли лучший способ включить текст шаблона или лучшее место для размещения шаблона?

Любые ссылки на модули CPAN, которые делают что-то подобное, приветствуются.

Заранее спасибо.

Ответы [ 7 ]

9 голосов
/ 13 апреля 2009

Каждый perl-файл имеет доступ к переменной __FILE__, которая сообщает ему полный путь. Нечто подобное должно сработать:

my $DEFAULT_TEMPLATE;
BEGIN {
    $DEFAULT_TEMPLATE = __FILE__;
    $DEFAULT_TEMPLATE =~ s,\.pm$,/default_email.tt,;
}

Тем не менее, если все, что вам нужно, это связать файлы данных с вашими модулями, взгляните на File :: ShareDir , который предоставляет способ сделать это.

7 голосов
/ 03 декабря 2009

Использование% INC может вводить в заблуждение в тех случаях, когда файл не совсем совпадает с именем пакета. (Это анти-паттерн, но это случается, иногда по уважительным причинам.) Если вы хотите найти файлы, вам лучше всего подойдет токен __FILE__. Пример модуля, который может найти себя:

package Foo::Bar;

use Cwd qw(abs_path);
use File::Basename qw(dirname);

sub module_dir { abs_path(dirname(__FILE__)) }

1;

Использование:

use Foo::Bar;

print Foo::Bar->module_dir, "\n";
5 голосов
/ 03 декабря 2009

Вы можете использовать хэш %INC, если модуль уже загружен. Например:

## load the module
use Data::Dumper;

## output full path to Data::Dumper module loaded
print $INC{'Data/Dumper.pm'};

## see which module was loaded (if you have multiple folders with same modules)
print Dumper(\%INC);
3 голосов
/ 13 апреля 2009

Perl также записывает расположение файла в переменную% INC. Вы можете использовать это, когда __FILE__ не доступен. Подробнее см. Документацию в perlvar .

2 голосов
/ 13 апреля 2009

Переписано, чтобы отразить то, что я узнал в комментариях:

  • Найти путь модуля

    package FooBar;
    
    use File::Spec;
    sub location  {
    return File::Spec->rel2abs( __FILE__);
    }
    
  • Где разместить шаблон:

    Поскольку шаблон, скорее всего, будет редактируемым, возможно, даже кем-то, работающим в сети, я настоятельно рекомендую поместить его в каталог, где «код», содержащийся в шаблоне, не может быть выполнен.

    Представьте, что кто-то звонит: http://your.home.net/cgi-bin/default_email.tt

1 голос
/ 03 декабря 2009

Я использую этот псевдоним bash, чтобы найти местоположение модуля (например, посмотреть на его реализацию или взломать некоторые отладочные операторы печати):

perlwhere() {
    perl -wle'eval "require $ARGV[0]" or die; ($mod = $ARGV[0]) =~ s|::|/|g; print $INC{"${mod}.pm"}' $1
}
$ perlwhere Test::More
/usr/lib/perl5/5.8.8/Test/More.pm
1 голос
/ 03 декабря 2009

Вы можете использовать токен __FILE__, чтобы получить имя (включая путь) текущего файла. Если вы хотите узнать путь к другому модулю (уже загруженному), проверьте содержимое хеша %INC.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...