🐪 Perl — 1987

⬅️ Atlas · 🧟 Lenguajes que siguen vivos · 📚 Índice de clases

La cinta adhesiva de Internet. Durante los años 90, buena parte de la web dinámica del planeta funcionaba con guiones CGI en Perl. Esa época pasó, pero Perl no: sigue procesando texto, administrando sistemas y secuenciando genomas, con una nueva versión estable cada año.

🎯 Por qué está en este programa

Criterio de inclusión: Perl 5 se mantiene activamente y publica una versión estable anual; la documentación vigente corresponde a la serie 5.44. Viene instalado en prácticamente cualquier sistema Unix o Linux, sostiene herramientas que se usan a diario (git send-email, Bugzilla, cPanel, buena parte de la infraestructura de Debian) y sigue siendo dominante en bioinformática.

Entra porque muestra dos conceptos que el núcleo no expresa bien. El primero: las expresiones regulares como parte de la sintaxis del lenguaje, no como una biblioteca. Perl las integró tan a fondo que definió el estándar de facto —PCRE, Perl Compatible Regular Expressions— que hoy usan Python, JavaScript, PHP, Java, Go y casi todos los demás. Cuando escribes una regex en cualquier lenguaje, estás escribiendo Perl. El segundo: el contexto, un concepto que casi no existe fuera de aquí: en Perl la misma expresión devuelve cosas distintas según dónde se use, y entenderlo enseña a mirar con otros ojos la evaluación de expresiones.

Perl ya aparece resuelto en cada primos.md del programa y se ejecuta en CI; esta ficha es su historia y su porqué.

Año 18 de diciembre de 1987 (Perl 1.0); Perl 5 desde 1994
Autoría Larry Wall — lingüista de formación, y se nota en el diseño
Familia Scripting dinámico; influencias de C, sed, awk, shell y Lisp
Paradigma Multiparadigma: procedimental, funcional y OO
Tipado Dinámico, con sigilos que marcan la forma del dato ($, @, %)
Memoria Conteo de referencias
Ejecución Compilado a un árbol interno en cada arranque y ejecutado
Estado 🟡 Mantenido y en uso — administración, texto, bioinformática, sistemas heredados

📜 Historia

En 1987 Larry Wall trabajaba como administrador de sistemas y programador en un proyecto que necesitaba generar informes a partir de árboles de ficheros de texto. Las herramientas disponibles no le servían: awk no manejaba bien ficheros ni estructuras complejas, sed era demasiado limitado, el shell era frágil y C era demasiado ceremonioso para un guion. Escribió Perl para cubrir ese hueco concreto, y lo publicó en el grupo de noticias comp.sources.unix el 18 de diciembre de 1987.

Wall es lingüista de formación, y eso explica la filosofía del lenguaje mejor que cualquier decisión técnica. Sus dos lemas son deliberadamente contrarios a la corriente:

Perl 5, en 1994, fue la reescritura que lo convirtió en un lenguaje serio: referencias (y con ellas estructuras de datos anidadas), módulos, paquetes y orientación a objetos mediante bless. Un año después nació CPAN, el Comprehensive Perl Archive Network, que fue el primer gran repositorio de módulos de la historia — el antepasado directo de PyPI, npm, RubyGems y crates.io.

A finales de los 90, Perl era el lenguaje de la web: los guiones CGI en cgi-bin eran Perl casi por definición. Ese dominio se perdió frente a PHP, y luego frente a Python y Ruby.

El episodio Perl 6. Anunciado en el año 2000 como el rediseño total del lenguaje, se convirtió en uno de los desarrollos más largos de la historia del software. Durante quince años la comunidad quedó dividida entre un Perl 5 que "iba a ser sustituido" y un Perl 6 que no llegaba. Cuando por fin se estabilizó, era tan distinto que en 2019 se renombró como Raku y se declaró un lenguaje aparte. Perl 5 recuperó su nombre y su cadencia anual de versiones. La lección —el coste de anunciar un sucesor que no llega— es de las más citadas en gestión de proyectos de lenguajes, y conviene tenerla presente al estudiar cualquier migración mayor.

🏭 Dónde sobrevive hoy

🧠 Por qué no ha muerto

1. Las regex son parte del lenguaje. if ($linea =~ /^(\w+)\s+(\d+)$/) no llama a una función: =~ es un operador, /.../ es literal de patrón, y $1, $2 aparecen automáticamente. En Python o Java hay que importar un módulo, compilar el patrón y consultar un objeto de coincidencia. Para trabajo de texto intenso, la diferencia de densidad es enorme.

2. CPAN sigue siendo excepcional. Decenas de miles de distribuciones, con una cultura de pruebas inusualmente rigurosa: CPAN Testers ejecuta automáticamente la batería de pruebas de cada módulo en decenas de combinaciones de sistema operativo y versión de Perl, y publica los resultados. Pocos ecosistemas tienen algo comparable.

3. Compatibilidad hacia atrás casi obsesiva. Un guion de 1998 sigue funcionando. Cuando el lenguaje ha querido cambiar algo, lo ha hecho tras use feature o use v5.36, sin romper lo existente. Perl no tuvo su ruptura 2→3.

4. Ubicuidad. Está en cualquier sistema tipo Unix. Para un administrador que no puede instalar nada en una máquina ajena, eso lo convierte en la única opción.

🔄 Lo que se ha modernizado

El Perl que se escribe hoy no es el de los guiones CGI de 1998:

⚙️ Cómo se ejecuta hoy

perl --version          # ya está instalado en Linux y macOS

perl total.pl < entrada.txt
echo "15000 2 0.10" | perl total.pl
# Total: 27000.00

# Como una sola línea, que es donde Perl brilla:
perl -ne 'print if /ERROR/' registro.log
perl -pi -e 's/viejo/nuevo/g' *.conf

Ecosistema: cpanm (cpanminus) para instalar módulos, Carton para fijar versiones por proyecto (equivalente a un lockfile), perlbrew o plenv para gestionar varias versiones del intérprete, y Perl::Critic y perltidy para estilo y análisis estático. La documentación completa está en la propia máquina: perldoc perlre, perldoc -f split.

🧪 El programa de la clase 041 en Perl

use strict;
use warnings;

my $linea = <STDIN>;
chomp $linea;

my ($precio, $cantidad, $descuento) = split ' ', $linea;
my $total = $precio * $cantidad * (1 - $descuento);

printf "Total: %.2f\n", $total;

Recorrido, línea a línea.

Y ahora lo que hace de Perl lo que es. El procesamiento de texto:

while (my $linea = <STDIN>) {
    next unless $linea =~ /^(\d{4})-(\d{2})-(\d{2})\s+(\w+)\s+(\d+)$/;
    my ($anio, $mes, $dia, $producto, $unidades) = ($1, $2, $3, $4, $5);
    $ventas{$producto} += $unidades;
}
printf "%-15s %6d\n", $_, $ventas{$_} for sort keys %ventas;

Ocho líneas que analizan un registro con formato, validan cada fila contra un patrón, agregan por clave y emiten un informe ordenado. next unless es un modificador de sentencia —la condición va detrás, porque así se lee mejor en voz alta, decisión típicamente lingüística de Wall—, $1..$5 son las capturas del patrón, %ventas es un hash que se crea solo al usarlo, y for sort keys %ventas al final es otro modificador. Reproducir esto en cualquier lenguaje del núcleo cuesta el doble de líneas. Ese es el nicho donde Perl sigue siendo la mejor herramienta.

🔍 Qué reconocer si vienes de otro lenguaje

Si conoces… En Perl es…
x = 5 my $x = 5;
Lista / array my @a = (1, 2, 3); y el elemento es $a[0]
Diccionario my %h = (clave => 'valor'); y el elemento es $h{clave}
len(a) scalar @a — o simplemente @a en contexto escalar
re.match(p, s) $s =~ /p/ — operador, no función
s.replace(a, b) $s =~ s/a/b/g;
a.split(",") split /,/, $a
"".join(a) join '', @a
def f(a, b): sub f { my ($a, $b) = @_; ... } — los argumentos llegan en @_
try / except eval { ... }; if ($@) { ... } — o Try::Tiny de CPAN
import modulo use Modulo;
Referencia / puntero \@lista, \%hash, y se accede con ->

⚠️ Errores comunes al leerlo

📚 Fuentes y bibliografía


⏮️ Volver al Atlas · 🧟 Los lenguajes que siguen vivos · 🔗 Relacionadas: Tcl/Tk · Common Lisp · C