Pular para o conteúdo principal

Perl 5.42

Decisão: Perl 5.42 é a versão mínima do stack. A declaração requires 'perl', '5.042' no cpanfile faz o Carton validar isso automaticamente em toda instalação. Versões estáveis futuras (5.44+) são suportadas — 5.42 é o piso, não um pino fixo.


Por que Perl 5.42

O Perl 5.42 é a versão estável mais recente, recomendada oficialmente pelo perl.org, e oferece o ecossistema mais completo: imagem Docker oficial (perl:5.42), suporte integral no perlbrew e berrybrew, e todos os módulos CPAN relevantes testados contra ela.

Destaques relevantes para o stack em relação a versões anteriores:

  • use v5.42; — desde a versão 5.36, a pragma de versão ativa strict e warnings automaticamente. Em scripts e utilitários eng/, uma linha substitui as três tradicionais.
  • Palavra-chave class estável (desde 5.40) — o sistema de OO nativo saiu do estado experimental. O stack continua usando Moo por maturidade, suporte a roles e ampla base instalada no CPAN, mas class é a direção de longo prazo da linguagem.
  • Compatibilidade com o ecossistema — Mojolicious, Moo, Mojo::Pg e demais módulos do stack testam ativamente contra as versões mais recentes.

A versão mínima está declarada como 5.042 (não 5.42) porque o cpanfile usa a notação numérica do módulo version, onde 5.42 e 5.042 são representações equivalentes da mesma versão. Versões estáveis posteriores (5.44, 5.46…) são compatíveis — o stack não impõe um teto.

Referências: perl.org · perl5/perl5 no GitHub · Modern Perl (livro)


Convenções obrigatórias no stack

Cabeçalho padrão de todo arquivo .pm

package Stega::Controller::Ticket;
use Mojo::Base 'Mojolicious::Controller'; # controllers
# — ou —
use Moo; # modelos de domínio
use namespace::clean;

use Mojo::Base e use Moo ativam strict e warnings implicitamente. Nunca use use strict; use warnings manualmente em módulos do stack — é redundante.

Scripts e pontos de entrada

#!/usr/bin/env perl
use Mojo::Base -strict; # ativa strict + warnings + utf8 em uma linha

Utilitários eng/ que não usam Mojolicious usam use v5.42; diretamente:

#!/usr/bin/env perl
use v5.42; # ativa strict, warnings, utf8 e todos os features até 5.42

Arquivos de teste (.t)

# t/api/tickets.t
use v5.42;
use Test::More;
use Test::Mojo;

use v5.42; ativa strict e warnings — use strict; use warnings; em arquivos .t é redundante com Perl 5.42+ como mínimo.

class nativo — quando usar

O class do Perl 5.42+ (estável desde 5.40) substitui Moo somente quando o tipo não precisa de roles, lazy builders, coerce nem triggers:

use v5.42;

class Stega::DTO::TicketSummary {
field $id :param :reader;
field $title :param :reader;
field $status :param :reader = 'open';
}

Se o tipo precisar de with 'SomeRole', use Moo. O class nativo ainda não tem suporte a roles — esse é o critério de decisão.

Proibições explícitas

Padrão proibidoAlternativa moderna
use base 'Foo'use Mojo::Base 'Foo' ou use parent 'Foo'
Chamadas de método indiretas: new FooFoo->new
open(FILE, ">arquivo")open(my $fh, '>', 'arquivo')
$_ em tutoriais como "simplificação"variável nomeada explícita
use 5.010 (versão antiga)use v5.42 ou requires 'perl', '5.042'
use strict; use warnings em .tuse v5.42 (já ativa ambos desde 5.36)
our @EXPORT com ExporterFunções via Moo ou sem exportação

Instalação da versão correta

Linux / macOS — perlbrew

perlbrew --notest install perl-5.42.2
perlbrew switch perl-5.42.2
perl -v # confirma: version 42, subversion 2

Windows — berrybrew

berrybrew install 5.42.2_64
berrybrew switch 5.42.2_64
perl -v

Docker

FROM perl:5.42
# A imagem oficial já inclui perl 5.42.x e cpanm

Padrões de código adotados no stack

Referências e acessos

# Hashref — sempre com chave entre chaves
my $config = { host => 'localhost', port => 5432 };
my $host = $config->{host};

# Arrayref
my $ids = [1, 2, 3];
my $first = $ids->[0];

# Deref em loop
for my $ticket (@{$tickets}) { ... }

# Alternativa com array slice de hashref
my @titles = map { $_->{title} } @{$tickets};

Chamadas de método encadeadas (Mojolicious)

# Estilo fluente do Test::Mojo
$t->get_ok('/healthz')
->status_is(200)
->json_is('/status', 'ok');

# Mojo::UserAgent — chamada não-bloqueante
my $tx = $self->ua->get('https://api.exemplo.com/data');
my $data = $tx->result->json;

Operadores modernos

# Definedness check (//= é atribuição com defined-or)
my $port = $config->{port} // 5432;
$config->{timeout} //= 30;

# String repetition vs. list repetition
my $line = '-' x 40;
my @zeros = (0) x 5;

# Wantarray para contexto (use com parcimônia)
sub items { wantarray ? @list : \@list }

Tratamento de erros

# Exceptions — die com objeto ou string
eval {
my $result = $self->pg->db->query($sql, @params);
};
if (my $err = $@) {
$self->app->log->error("Query falhou: $err");
return $self->render(json => { error => 'internal' }, status => 500);
}

# Alternativa com Try::Tiny (não no stack por padrão)
# use Try::Tiny;
# try { ... } catch { ... };

Ferramentas de qualidade de código

# Verificação estática básica (sempre disponível)
perl -c lib/Stega/Controller/Ticket.pm

# Testes com TAP
carton exec prove -lr t/

# Cobertura de testes
PERL5OPT="-MDevel::Cover" carton exec prove -lr t/
carton exec cover # gera relatório HTML em cover_db/

# Perl::Critic (análise de estilo — não obrigatório, mas útil)
cpanm Perl::Critic
perlcritic lib/

Armadilhas comuns

ArmadilhaDescriçãoComo evitar
@array em contexto escalarRetorna contagem de elementos, não o primeiroUse $array[0] para o primeiro elemento
undef vs. string vaziaundef // '' é verdadeiro, undef || '' tambémUse // para verificar definição, || para verificar veracidade
Modificação de $_ em um loop aninhadoClobbers o $_ externoSempre use variável nomeada: for my $x (@list)
local/ ausente do $PATHcarton exec foi esquecidoPrefixe todos os comandos com carton exec
CRLF em scriptsScripts falham dentro de containers.gitattributes com eol=lf (ver ADR-012)