Jak korzystać z sabu z Perl skrypt

Zadanie. Jest skrypt w języku programowania Perl. W nim określona jakaś funkcja (saba). Trzeba заиспользовать tę funkcję w innym skrypcie.

Oto przykład. Istnieje skrypt script.pl , w którym jest zdefiniowana saba header. W ten sabu powiesz wiersz, i zwraca ten wiersz w postaci markdown tytułu. W tym skrypcie ta saba służy do tego aby wyświetlić dwa nagłówki:

▶ Run
#!/usr/bin/perl

use feature qw(say);

sub header {
    my ($string) = @_;

    return '## ' . uc($string);
}

say header('one');
say header('two');

Uruchamiamy perl script.pl i widzimy na ekranie:

## ONE
## TWO

Zadanie — stworzyć jeszcze jeden skrypt other.pl , który też będzie korzystać z tej sabu.

Rozwiązanie — copy-paste

Najprostsze (ale słaby) rozwiązanie to po prostu skopiować kod ruchy w inny skrypt. Przy takim rozwiązaniu okazuje się to taka other.pl:

#!/usr/bin/perl

use feature qw(say);

sub header {
    my ($string) = @_;

    return '## ' . uc($string);
}

say header('three');

Można teraz uruchomić ten skrypt perl other.pl i zobaczyć na ekranie tekst ## THREE.

To rozwiązanie problemu, ale to jest złe rozwiązanie. Z powodu tego, że jeden i ten sam kod jest w wielu plikach trudno jest pracować z takim kodem. Kiedy trzeba zmienić ten sabu, to będzie musiał zmienić ją w kilku miejscach (i jeszcze będzie trzeba nie zapomnieć zmienić kod w odpowiednich plikach).

Rozwiązanie — wynieść sabu w oddzielny moduł

Najbardziej właściwe rozwiązanie, to wynieść sabu w oddzielny moduł. Do tego tworzymy plik lib/Utils.pm:

package Utils;

use strict;
use warnings;

use Exporter;

our @ISA = qw(Exporter);
our @EXPORT_OK = qw(
    header
);
our @EXPORT = @EXPORT_OK;

sub header {
    my ($string) = @_;

    return '## ' . uc($string);
}

1;
  • package Utils; - ogłosili że to "biblioteka" Utils
  • use strict; i use warnings; — włączamy tryb, aby Perl był bardziej wymagający do dobrego kodu
  • 5 wiersze o EXPORT mówią o tym, że po podłączeniu tej "biblioteki" trzeba aby funkcja header była dostępna
  • przeniesiono tu funkcję
  • 1; — package zawsze musi kończyć się prawdą

Po tym opis funkcji trzeba z skrypt script.pl wywalić, ale dodać połączenie biblioteki:

#!/usr/bin/perl

use feature qw(say);

use Utils;

say header('one');
say header('two');

Po tym można uruchomić ten skrypt za pomocą polecenia perl -Ilib/ script.pl. W przełącznik wiersza polecenia -I przekazujemy wartość lib/ — folder w którym Perl będzie szukać biblioteki. Wynik działania tego skryptu jest dokładnie taki sam jak wcześniej.

I teraz zupełnie trywialne заиспользовать ten sam sabu w innym skrypcie. Piszemy skrypt other.pl, który jest praktycznie taki sam jak script.pl:

#!/usr/bin/perl

use feature qw(say);

use Utils;

say header('three');

Uruchom ten skrypt perl -Ilib/ other.pl i widzimy na ekranie ## THREE.

Rozwiązanie — podłączyć kod skryptu do skryptu

Istnieje jeszcze jedno rozwiązanie, jak można korzystać z sabu określoną w skrypcie script.pl заиспользовать w skrypcie other.pl. Do tego piszemy ten tekst w plik other.pl:

#!/usr/bin/perl

use feature qw(say);

require './script.pl';

say header('three');

Uruchamiamy skrypt perl other.pl (plik other.pl musi być w tym samym katalogu co skrypt script.pl). Wynik:

## ONE
## TWO
## THREE

Czyli okazało się, że podczas wykonywania skryptu other.pl po raz pierwszy został wykonany cały kod, który był w script.pl (ciąg ## ONE i ## TWO), a dopiero potem jest wykonany kod ze skryptu other.pl (ciąg ## THREE).

Aby po uruchomieniu skryptu other.pl nie przeprowadzono część script.pl potrzebujemy trochę zmienić script.pl. Trzeba zawinąć cały kod w treści skryptu pod warunkiem i wpisać na końcu skryptu jednostkę jak prawdziwe znaczenie:

#!/usr/bin/perl

use feature qw(say);

sub header {
    my ($string) = @_;

    return '## ' . uc($string);
}

if ( not caller() ) {
    say header('one');
    say header('two');
}

1;

Teraz jeśli odpalimy perl script.pl, to otrzymamy dokładnie taki sam wniosek jak i wcześniej, a jeśli użyjemy perl other.pl, to na wyjściu będzie tylko odpowiedni tekst do nas ## THREE.

Słowo kluczowe caller zwraca różne wartości w zależności od tego jak został uruchomiony skrypt. Tę funkcjonalność używamy tutaj, aby podzielić uruchomienie skryptu bezpośrednio od połączenia skryptu z wykorzystaniem require.

Inne artykuły