2010-11-03 8 views
7

Perl automatically initializes variables na undef domyślnie.Jak mogę automatycznie zainicjować wszystkie zmienne skalarne w Perlu?

Czy istnieje sposób na przesłonięcie tego domyślnego zachowania i poinformowanie interpretera Perla o zainicjowaniu zmiennych do zero (lub innej stałej wartości)?

+0

Inicjowanie zmiennych do 'undef' jest nadal inicjalizacją. – zigdon

+7

Czy mogę zapytać, dlaczego chciałbyś to zrobić? – Zaid

+0

@Zaid: Cała historia - czytam Code Complete (który wspomina zawsze o inicjalizowaniu zmiennych podczas deklaracji, jeśli to możliwe) i przeglądał jeden z moich starych plików, który używa wielu liczników, które początkowo zainicjowałem na "zero" ale później usunięto wszystkie niepotrzebne inicjalizacje. Zastanawiam się nad ponownym wprowadzeniem wszystkich inicjalizacji i zadałem to pytanie, aby znaleźć lepszy sposób na zrobienie tego. – Lazer

Odpowiedz

12

Zalecenie w Kodeksie Complete jest ważne dla języka takich jak C, ponieważ kiedy masz

int f(void) { 
    int counter; 
} 

wartość counter to co dzieje się zajmować, że pamięć.

W Perl, kiedy zadeklarować zmienną korzystając

my $counter; 

nie ma wątpliwości, że wartość $counter jest undef nie jakiś przypadkowy śmieci.

Dlatego motywacja zalecenia, tj. Zapewnienie, że wszystkie zmienne zaczynają się od znanych wartości, jest automatycznie spełniana w Perlu i nie jest konieczne wykonywanie żadnych czynności.

To, co robisz z licznikami, to ich zwiększanie lub zmniejszanie. Wynik:

my $counter; 
# ... 
++ $counter; 

jest dobrze zdefiniowany w Perlu. $counter będzie mieć wartość 1.

Na koniec, argumentowałbym, że w większości przypadków liczniki nie są konieczne w Perlu i kod może wymagać ponownego napisania kodu z szerokim wykorzystaniem zmiennych licznika.

+2

+1 za niezamaskowanie z eleganckim wyjaśnieniem – daxim

+2

Kiedy * przepisano * zamieniono na * refaktoryzowane *, w każdym razie? ☺ – tchrist

5

Nie. Może to prowadzić do bardzo przerażających i trudnych do odszyfrowania błędów, więc i tak nie jest dobrym pomysłem, aby zmienić takie zachowanie.

W Perlu, możesz zadeklarować zmienne dokładnie wtedy, gdy ich potrzebujesz po raz pierwszy, więc generalnie nie ma potrzeby zadeklarowania ich jako pierwszych (z inicjalizacją lub bez), a następnie później. Dodatkowo, podmioty takie jak ++ będzie pracować z wartościami niezdefiniowanych równie dobrze jako zero, więc nie trzeba zainicjować liczników w ogóle:

# this is perfectly legal: 
my $counter; 
while ($some_loop) 
{ 
    $counter++; 
} 

Mogę jednak włożyć wtyczkę do Moose przez wspomnieć, że można osiągnąć automatyczna inicjalizacja atrybutów w swoim Moose klas:

package MyClass; 
use strict; 
use warnings; 
use Moose; 

has some_string => (
    is => 'rw', isa => 'Str', 
    default => 'initial value', 
); 

has some_number => (
    is => 'rw', isa => 'Int', 
    default => 0, 
); 
__PACKAGE__->meta->make_immutable; 
1; 

package main; 
my $object = MyClass->new; 
print "string has value: ", $object->some_string, "\n"; 
print "number has value: ", $object->some_number, "\n"; 

drukuje:

ciąg ma wartość: wartość początkową
liczba ma wartość: 0

11

O ile mi wiadomo, nie jest to możliwe (i nie powinno być, nawet bardziej niebezpieczne niż $[).

można zainicjować zmienne w następujący sposób, aby obniżyć boilerplate:

my ($x, $y, $z) = (0) x 3; 

lub przenieść inicjalizacji do funkcji:

sub zero {$_ = 0 for @_} 

zero my ($x, $y, $z); 

lub nawet:

$_ = 0 for my ($x, $y, $z); 
+0

dzięki. btw, jak to jest '$ [' niebezpieczne? – Lazer

+1

jest to indeks, od którego zaczynają się tablice. było tam, aby perl zachowywał się jak awk, ustawiając go na 1. jest przestarzały i ostrzega, a jedynie ma zasięg pliku i musi być ustawiony w czasie kompilacji ze względu na wszystkie błędy, które mógł spowodować w niepowiązanym kodzie. perldoc perlvar, aby uzyskać więcej informacji –

+0

Nie można zrozumieć, dlaczego w punkcie zgłoszenia trzeba zainicjować coś do zera. – tchrist

0

Lubisz mają konkretny powód, by chcieć to zrobić, czy jest to po prostu "dlatego, że Code Comple te mówi, że powinienem "?

Jeśli to pierwsze, proszę podać przyczynę i możemy omówić właściwie Perly sposoby, aby osiągnąć swój prawdziwy cel.

Jeśli to ostatnie, proszę pamiętać, że Code Complete to zestaw wytycznych do programowania w języku C, nie w języku Perl. Perl nie jest C i ma swój własny zestaw mocnych i słabych stron, co oznacza również, że ma inny zestaw ... i nienawidzę używać tego zwrotu ... najlepszych praktyk. Wytyczne odpowiednie dla jednego języka niekoniecznie odnoszą się do drugiego. "Zawsze inicjuj zmienne (jeśli to możliwe), gdy je deklarujesz" jest praktyką dźwiękową w C, ale na ogół niepotrzebną w Perlu.

Powiązane problemy