2013-02-09 14 views
12

Mam zamiar przekazać dwie zmienne do funkcji perl, z których jedna może być opcjonalna. Próbuję sprawdzić, czy drugi jest zdefiniowany, czy nie, ale nie działa poprawnie. Kiedy nazwałem funkcję myFunction (18), zakłada ona, że ​​zmienna $ opcjonalna jest zdefiniowana i przechodzi do instrukcji else. Ale w instrukcji else, gdy dostępna jest zmienna $ optional, generuje błąd "niezainicjowany". Jest dokładnie odwrotnie, niż się spodziewałem. Każda pomoc jest bardzo doceniana.Używanie zdefiniowanego/undef w Perlu

sub myFunction { 
    my ($length, $optional) = (@_); 
    if(undef($optional) 
    { 
    more code.. 
    } 
    else 
    { 
    more code... 
    } 
} 

myFunction(18) 
+4

Jeśli próbujesz dowiedzieć się, ile są przekazywane, a następnie przyjmują liczbę argumentów: 'skalar (@_)'. Jeśli nazwiesz 'foo (4, undef)', zdałeś 2 argumenty. –

+0

To dlatego, że test dla niezdefiniowanej wartości to ['nie zdefiniowane'] (http://perldoc.perl.org/functions/defined.html), a nie [' undef'] (http://perldoc.perl.org /functions/undef.html). – hd1

Odpowiedz

21

Poprawną funkcją jest defined. undef undefines $optional. Co chcesz zrobić, to coś takiego:

sub myFunction { 
    my($length, $optional) = @_; 
    if(! defined $optional) { 
     # Do whatever needs to be done if $optional isn't defined. 
    } 
    else { 
     # Do whatever can be done if $optional *is* defined. 
    } 
} 

Innym sposobem radzenia sobie z nim (zwłaszcza Perl 5.10+) jest użycie "zdefiniowane lub" operator, // coś takiego:

sub MyFunc { 
    my $length = shift; 
    my $optional = shift // 'Default Value'; 
    # Do your stuff here. 
} 

To, co robi, jest wykrywanie, czy zdefiniowana jest wartość zwracana shift @_. Ponieważ już raz wywołałeś zmianę, testujemy teraz drugi parametr. Jeśli jest zdefiniowany, przypisz wartość do $optional. Jeśli nie jest zdefiniowany, przypisz 'Default Value' do $optional. Oczywiście musisz wymyślić własną rozsądną wartość domyślną.

Jeśli utkniesz w ciemnych wieków wstępnej Perl 5.10, można osiągnąć to samo z:

my $optional = shift; 
$optional = defined $optional ? $optional : 'Default value'; 

... albo ...

my $length = shift; 
my $optional = defined($_[0]) ? shift : 'Default value'; 

Tak czy inaczej, Często wolę mieć domyślne ustawienie, a nie całkowicie oddzielną ścieżkę przepływu sterowania. Często jest to dobry sposób na uproszczenie kodu.

+1

'$ SCALAR = undef;' po prostu nie definiuje. 'undef (VAR)' robi o wiele więcej, nawet dla skalarów. (Uwalnia różne bity pamięci.) – ikegami

+0

@ikegami To prawda, ale po co komplikować? Utknąłem z zachowaniem udokumentowanym w 'perldoc -f undef'. Być może chodzi o słowo "tylko". Usuwam to. – DavidO

+0

co to jest "shift"? –

0
my $optional = defined($_[0]) ? shift : 'Default value'; 

Jest to kod niebezpieczny, gdyż tylko przesuwa się parametr jeśli zdefiniowane, jeśli miał trzeci parametr ten dostanie zagmatwane, kiedy zadzwonić

MyFunc(10, undef, 20)