Как я могу распространять свое Perl-приложение в виде одного файла?

StackOverflow https://stackoverflow.com/questions/1415782

  •  06-07-2019
  •  | 
  •  

Вопрос

У меня есть сценарий Perl (foo.pl), который загружает Foo.pm из того же каталога, используя механизм require:

require "./Foo.pm";
...
my $foo = new Foo::Bar;

Foo.pm придерживается стандартного формата модуля:

package Foo::Bar;
...
1;

Вместо того, чтобы распространять свое приложение в виде двух файлов (foo.pl и Foo.pm), я хотел бы распространять только один файл.Более конкретно, я хотел бы сделать Foo.pm частью сценария foo.pl.

Как мне этого добиться?

Тривиальный подход — простое объединение двух файлов (cat foo.pl Foo.pm > foo2.pl) не работает.

Это было полезно?

Решение

Ваш код не работал (хотя было бы полезно указать полученные вами сообщения об ошибках), поскольку вы попытались использовать Foo::Bar до того, как он был определен.Попробуй это:

use strict;
use warnings;
my $foo = Foo::Bar->new();
# more code...

# end code

# begin definitions
BEGIN {
    package Foo::Bar;
    use strict;
    use warnings;
    # definitions...
    1;

    package Foo::Baz;
    # more stuff, if you need to define another class
}

Дополнения:

Другие советы

Если вы заинтересованы в упаковке скрипта Perl в двоичный файл со всеми модулями, от которых он зависит, вы можете использовать PAR Packager :

pp -o binary_name foo.pl

Файл может содержать несколько пакетов. Сначала поместите ваш класс, а затем основной скрипт:

package Foo::Bar;

sub new { 
  my $class = shift;
  return bless {}, $class;
}

#...

package main;

my $foo = Foo::Bar->new();
print ref $foo;  # Foo::Bar

Общая схема заключается в замене вашего " требовать ... " с содержанием того, что вам требуется. Это больше, чем это (BEGIN {} может понадобиться), и я не совсем уверен, в чем дело. Конечно, вы хотели бы автоматизировать это.

Вот альтернатива: создайте один исполняемый файл, в котором модули, от которых вы зависите, упакованы в него, используя PAR / pp

У вас уже есть несколько хороших ответов. Кроме того, можно создать модуль, который можно запустить непосредственно в виде скрипта.

package Foo;

__PACKAGE__->run(@ARGV) unless caller();

sub run {
    # Do stuff here if you are running the Foo.pm as
    # a script rather than using it as a module.
}

Дополнительные сведения см. в Брайана Д. Фоя о том, как скрипт становится модулем .

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top