2009-09-20 12 views
14

Mam kilka plików Perla, które pobierają niektóre stałe nazwy pliku. Chciałbym je zdefiniować w oddzielnym pliku - coś jak plik nagłówkowy w C. Jaki jest najlepszy/najbardziej standardowy sposób robienia tego w Perlu?Jak zdefiniować stałe w oddzielnym pliku w Perlu?

+2

Bardzo bliski duplikat tego pytania: http://stackoverflow.com/questions/193020/how-do-i-use-constants-from-a-perl-module – draegtun

Odpowiedz

16

Brak odpowiedników plików nagłówkowych C w Perlu. Aby zadeklarować i zdefiniować stałe globalne, można użyć pragma define. Nie mam doświadczenia z tym modułem, chociaż interfejs wydaje się rozsądny.

Z drugiej strony można napisać moduł, w którym definiuje się stałe i importować je do modułu przy użyciu numeru use. Na przykład:

package MyConstants; 

use strict; use warnings; 

use Exporter qw(import); 
use Const::Fast; 

our @EXPORT = qw(); 
our @EXPORT_OK = qw($X $Y); 

const our $X => 'this is X'; 
const our $Y => 'this is Y'; 

__PACKAGE__; 
__END__ 

Następnie można użyć tego modułu, co następuje:

#!/usr/bin/perl 

use strict; use warnings; 

use MyConstants qw($X); 

print "$X\n"; 
print "$MyConstants::Y\n"; 

Jeśli są OK, z użyciem w pełni kwalifikowanych nazw zmiennych (np $MyConstants::Y), nie trzeba Exporter w ogóle.

Upewnij się także, że zmienne, które eksportujesz, nie są modyfikowane w innym miejscu (patrz uwaga w dokumentach Exporter).

Oczywiście można również zdefiniować stałe za pomocą constant.pm. Szybsze może być użycie takich stałych, ale są one niezręczne, jeśli trzeba je interpolować w ciągu znaków.

+3

Readonly :: Scalar jest dość szybki, jeśli masz zainstalowany Readonly :: XS. Hashe and Arrays są jednak wolniejsze. –

+1

Należy pamiętać, że dokumentacja eksportera (http://perldoc.perl.org/Exporter.html) zaleca, aby NIE eksportować zmiennych, nawet jeśli pozwala. –

+2

@Robert P, IMO eksportując zmienną na życzenie jest uzasadnione, najlepiej unikać eksportu jednego (lub więcej!). Jeśli w powyższym przykładzie spodziewałem się użyć X wiele razy, wiele razy i chciałem uniknąć niepotrzebnego powtarzania wpisywania '$ MyConstants :: X' wszędzie, byłoby to ogromną korzyścią. Innym przypadkiem dla zaimportowanych zmiennych jest to, że jeśli przypadkowo próbowałem użyć '$ MyConstants :: x', żaden komunikat' strict' generowany błąd nie ostrzegłby mnie o moim błędzie, podczas gdy, jeśli zaimportuję '$ X' i spróbuję użyć' $ x', ścisły zapisuje dzień przez uchwycenie błędu. – daotoad

-2

Jednym ze sposobów byłoby napisanie ich jako modułu perla, który następnie można dołączyć za pomocą "wymagaj" lub "używaj". Można by napisać plik tak - nadać mu rozszerzenie .pm (np myFabulousPackage.pm)

package myFabulousPackage; 

$someSetting=45; 
$otherSetting='Fish'; 

1; 

Następnie w skrypcie Perl, będzie to obejmować plik, a następnie odwołać $ otherSetting:

#!/usr/bin/perl 

use myFabulousPackage; 

print $myFabulousPackage::otherSetting; 

To jest bardzo prosty widok na to, co można zrobić z pakietem/modułem, ale w razie potrzeby może to być najprostszy sposób wdrożenia. Podobnie możesz umieścić subs w paczce i odnosić się do nich w podobny sposób.

+3

To nie zadziała. Zmienne zadeklarowane za pomocą moich (zmiennych leksykalnych) nie są dostępne za pośrednictwem '$ NazwaPakietu :: NazwaZmiany'. Ta składnia ma tylko dostęp do zmiennych w tabeli symboli. Najlepszym sposobem na umieszczenie zmiennych w tabeli symboli jest użycie 'nasz' do ich zadeklarowania. – daotoad

+1

To nie zadziała.Deklaracja zmiennych "my" powoduje, że są one leksykalnie ograniczone, a zatem widoczne tylko dla kodu w pliku '.pm'. Chcesz, aby zostały one zadeklarowane zamiast "nasz". Warto również zawsze usuwać pliki modułów za pomocą '1;', ponieważ jeśli ostatnia instrukcja jakoś okaże się fałszywą wartością, moduł się nie załaduje. – arnsholt

+0

Yep - masz rację co do "mojego" ... to ja piszę perl na autopilocie, a nie podwójnie sprawdzam moich przykładów. Edycja. –

7

Zwykle robimy to z nazwą modułu Stałe. Coś jak:

package MyPackage::Constants; 

our $DIR = "/home/chriss"; 
our $MAX_FILES = 5; 

1; 

Następnie, aby go użyć:

package MyPackage; 
use MyPackage::Constants; 

open(my $fh, ">", $MyPackage::Constants::DIR . "/file"); 

Jeśli nie chciał odwoływać pakietu cały czas, można użyć eksporter i sprowadzić wszystkich symboli, które chcesz.

+3

Dlaczego nie definiować stałych MyPackage w samym module MyPackage, zamiast tworzyć nowy obszar nazw? A jeśli odwołasz się do stałej jako przestrzeni nazw :: DIR, tracisz przewagę dziedziczenia, tj. MyPackage :: Child :: Constants nie może dziedziczyć z MyPackage :: Constant i nadpisywać wartości DIR. namespace-> DIR jest znacznie lepszy. – Ether

+1

Jest to uproszczony przykład do celów poglądowych. Powiedział, że nie wszystko jest OO :) –

+4

To wygląda jak konfiguracja, a nie stałe. –

5

To brzmi jak ustawienia konfiguracyjne, które lepiej byłoby umieścić w pliku konfiguracyjnym, który analizuje się za pomocą jednego z różnych modułów CPAN, na przykład Config::Any.

Konfiguracja to dane, których IMO nie powinno znajdować się w kodzie.

Powiązane problemy