Em algumas linguages existe uma forma especial de se dizer "este campo não possui valor". No SQL, PHP e Java é através do NULL. Em Python é None e em Ruby é chamado Nill.

Em Perl o valor é chamado undef.

Vamos ver alguns detalhes.

De onde você recebe valores undef?

Quando você declara uma variável escalar sem atribuir um valor a ela, o conteúdo será definido como undef.

my $x;

Algumas funções retornam undef para indicar uma falha. Outras podem retornar undef se elas não possuem nada a retornar.

my $x = faça_algo();

Você pode usar a função undef para resetar uma variável à undef:

# código
undef $x;

Você pode até mesmo utilizar o valor de retorno da função undef para atribuir undef a uma variável:

$x = undef;

Os parênteses após o nome da função são opcionais, e neste caso eu omiti para exemplificar.

Como você pode observar existe diferentes formas de atribuir undef a uma variável. A questão aqui é, o que acontece quando você utiliza uma dessas variáveis?

Mas antes disso, vamos ver um outro tópico:

Como verificar se o valor de uma variável não é definido?

A função defined() irá retornar verdadeiro se o valor em questão não for não definido. E irá retornar falso se o valor não for definido, ou undef.

Você pode utilizá-la da seguinte forma:

use strict;
use warnings;
use 5.010;

my $x;

# aqui em cima há algum código que define $x

if (defined $x) {
    say '$x é definida';
} else {
    say '$x é undef';
}

Qual é o verdadeiro valor de undef?

Enquanto undef indica a ausência de valor, ainda assim não pode ser utilizado. O Perl oferece dois valores padrão para serem utilizdos no lugar de undef.

Se você utiliza uma variável que é undef em uma operação numérica, ela atua como se fosse 0.

Se você a utiliza em uma operação de texto, ela atua como se fosse um texto vazio.

Veja os exemplos a seguir:

use strict;
use warnings;
use 5.010;

my $x;
say $x + 4, ;  # 4
say 'Foo' . $x . 'Bar' ;  # FooBar

$x++;
say $x; # 1

No exemplo acima a variável $x - que é undef por padrão - age como 0 na adição (+). No caso da concatenação (.), age como se fosse um texto vazio, e novamente como 0 durante o auto incremento (++).

Mesmo assim, não é algo à prova de falhas. Se você tivesse pedido para ativar os avisos pelo pragma use warnings (que é bastante recomendado) então teria dois avisos de valor não inicializado para as duas primeiras operações, porém não para o auto incremento:

Use of uninitialized value $x in addition (+) at ... line 6.
Use of uninitialized value $x in concatenation (.) or string at ... line 7.

Depois iremos ver que isso é bastante conveniente em lugares onde você gostaria de contar coisas.

É claro que você pode também evistar os avisos através da inicialização das variáveis no valor incial correto (0 ou um texto vazio, dependendo do que esteja fazendo), ou pela possibilidade de desligar seletivamente os avisos. Nós vamos discturi isso em um outro artigo.