undef w Perl

undef w języku programowania Perl — to jedna z wartości, która może być zmienna. Jeśli nie przypisać zmiennej wartość, to w zmiennej znajduje się undef.

Oto przykład Perl programu:

▶ Run
#!/usr/bin/perl

use strict;
use warnings;
use Data::Dumper;

my $var;
print Dumper $var;

$var = 123;
print Dumper $var;

$var = undef;
print Dumper $var;

Ten program wypisze na ekran:

$VAR1 = undef;
$VAR1 = 123;
$VAR1 = undef;

Najpierw deklarujemy zmienną, ale nie nadano jej znaczenia: my $var;. Dalej z pomocą print Dumper $var; czerpali informacje na temat wartości tej zmiennej na ekran (widać, że w zmiennej zawiera undef). Wtedy my przypiszemy zmiennej liczba 123i pokazywali to na ekranie. A dalej za pomocą kodu $var = undef; my przypiszemy zmiennej undef i znowu wyprowadzili się informacje o tym.

undef może być elementem w tablicy lub wartością w хеше:

▶ Run
#!/usr/bin/perl

use strict;
use warnings;
use Data::Dumper;

my @arr = (1, undef, 'three');
print Dumper \@arr;

my %h = (
    a => undef,
);
print Dumper \%h;

Często undef jest używany jako specjalny flaga. Na przykład, może to być funkcja, która zawsze zwraca liczbę, ale w przypadku błędu zwraca undef.

Nazwa undef pochodzi od angielskiego słowa undefined("abstrakt").

Niż undef nie jest

undef — to osobne znaczenie. To nie wiersz 'undef', to nie pusty wiersz '' i nie jest to liczba 0. Wszystko to — różne wartości.

▶ Run
#!/usr/bin/perl

use strict;
use warnings;
use Data::Dumper;

foreach my $var (undef, 'undef', '', 0) {
    print Dumper $var;
}

W przypadku mieszania jeśli wartość klucza undef to nie to samo, co w хеше brakuje taki klucz.

Jak sprawdzić na undef

Aby sprawdzić, czy wartość undef służy funkcja defined. Wartość jest undef jeśli funkcja defined zwraca fałsz:

▶ Run
#!/usr/bin/perl

use strict;
use warnings;

my $var;

if (!defined($var)) {
    print 'var is undef';
}

Bardzo łatwo napisać sabu is_undef, która zwraca prawdę, jeśli w niej przekazali undef:

▶ Run
#!/usr/bin/perl

use strict;
use warnings;
use feature qw(say);
use Data::Dumper;

sub is_undef {
    my ($maybe_undef) = @_;
    return !defined($maybe_undef);
}

my @arr = (1, undef, 'three');

foreach my $el (@arr) {
    say is_undef($el) ? 'undef' : 'not undef';
}

Ale najczęściej tak nie robią, a korzystają z funkcji defined bez żadnego osprzętu.

Istnieje jeszcze jeden sposób, jak można sprawdzić co jest w zmiennej zawiera undef — to użyć operatora ~~ (operator ten nazywa smartmatch). Operator ten pojawił się w Perl 5.10, ale od wersji Perl 5.18 użycie tego operatora wyświetla ostrzeżenie Smartmatch is experimental at script.pl line 8.. Oto przykład kodu z tym operatorem:

▶ Run
#!/usr/bin/perl

use strict;
use warnings;

my $var;

if ($var ~~ undef) {
    print 'var is undef';
}

Najczęściej jest najlepszym sposobem, aby sprawdzić na undef to funkcja defined.

Perl undef i konwersja do formatu JSON

Biblioteki do pracy z JSON w Perl przekształcają Perl wartość undef w null w formacie JSON:

▶ Run
#!/usr/bin/perl

use strict;
use warnings;
use JSON::PP;

print encode_json {
    a => undef,
};

Ten kod wyświetla {"a":null}.

I odwrotnie, przy konwersji z formatu JSON null staje się undef:

▶ Run
#!/usr/bin/perl

use strict;
use warnings;
use JSON::PP;
use Data::Dumper;

print Dumper decode_json '[null]';

Ten kod wyświetli na ekranie:

$VAR1 = [
          undef
        ];

Funkcja ref

Wynik działania funkcji ref w odniesieniu do undef — to pusty ciąg ''. W tym zakresie undef nie różni się od ciągów znaków i liczb. Dla undef, ciągów i liczb funkcja ref zwraca pusty ciąg znaków:

▶ Run
#!/usr/bin/perl

use strict;
use warnings;
use Data::Dumper;

foreach my $el ('asdf', undef, 100) {
    print Dumper ref($el);
}

Wartość logiczną

Podczas korzystania z undef w operacjach logicznych undef — to kłamstwo. Ten kod wyświetli ekran tekst false:

▶ Run
#!/usr/bin/perl

use strict;
use warnings;
use Data::Dumper;

if (undef) {
    print 'true';
} else {
    print 'false';
}

Korzystanie z wierszami

W tym przypadku użyć undef w operacjach na stringach, to zamiast undefbędzie używane pusty wiersz '', ale również pojawia się ostrzeżenie.

▶ Run
#!/usr/bin/perl

use strict;
use warnings;

my $var;

print 'AAA' . $var . 'BBB';
▶ Run
#!/usr/bin/perl

use strict;
use warnings;

my $var;

if ($var eq '') {
    print 'equal';
} else {
    print 'not equal';
}

W pierwszym przypadku pojawi się ostrzeżenie Use of uninitialized value in concatenation (.) or string at script.pl line 10., w drugim przypadku Use of uninitialized value in string eq at script.pl line 8..

Korzystanie z liczbami

W tym przypadku użyć undef w operacjach z liczbami, zamiast undefbędzie używany liczba 0. ale tak samo wyświetlone zostanie ostrzeżenie.

▶ Run
#!/usr/bin/perl

use strict;
use warnings;

my $var;

print $var + 4;
▶ Run
#!/usr/bin/perl

use strict;
use warnings;

my $var;

if ($var == 0) {
    print 'equal';
} else {
    print 'not equal';
}

W pierwszym przypadku pojawi się ostrzeżenie Use of uninitialized value $var in addition (+) at script.pl line 8., w drugim przypadku Use of uninitialized value $var in numeric eq (==) at script.pl line 8..

Ciekawe, że przy użyciu operatora inkrementacji ++ ostrzeżenia nie:

▶ Run
#!/usr/bin/perl

use strict;
use warnings;

my $var;

print $var++;

Tematy pokrewne

Inne artykuły