Mostrando entradas con la etiqueta perl. Mostrar todas las entradas
Mostrando entradas con la etiqueta perl. Mostrar todas las entradas

lunes, 16 de marzo de 2026

WebSockets con Mojolicious

En esta ocasión veremos un ejemplo sencillo de WebSockets con Mojolicious.

Como vimos en entregas pasadas:

Mojolicious es un framework para Perl que es similar a Dancer2, pero más completo. Además nos permite trabajar con WebSockets, que es el tema que vamos a ver. Como vimos en una entrega anterior, los WebSockets son un protocolo que permite comunicación bidireccional en tiempo real entre cliente y servidor, a diferencia de HTTP que funciona en modo solicitud-respuesta.

Observemos el siguiente código.

web_socket.pl

use Mojolicious::Lite -signatures;

# Renderiza la plantilla "index.html.ep" desde la seccion 
get '/' => sub ($c) {
  $c->render(template => 'index');
};

# Servicio WebSocket usado por la plantilla para extraer el título del sitio web
websocket '/title' => sub ($c) {
  $c->on(message => sub ($c, $msg) {
    my $title = $c->ua->get($msg)->result->dom->at('title')->text;
    $c->send($title);
  });
};

app->start;
__DATA__

@@ index.html.ep
% my $url = url_for 'title';
<script>
  const ws = new WebSocket('<%= $url->to_abs %>');
  ws.onmessage = function (event) { document.body.innerHTML += event.data };
  ws.onopen    = function (event) { ws.send('https://www.wikipedia.org') };
</script>

En este programa Perl hacemos uso del Framework Mojolicious. Donde se mostrará una sencilla página HTML que obtendrá el nombre del sitio web definido dentro de la función ws.send("web_page"). En este caso obtendremos el título de la página de Wikipedia.

Lo ejecutaremos de la siguiente manera:

$ perl web_socket.pl daemon -l http://*:8080

Abrimos un navegador en la ruta: http://127.0.0.1:8080/

También podemos ejecutar de este modo:

$ morbo web_socket.pl

En este caso, abrimos un navegador en la ruta: http://127.0.0.1:3000/

Salida:

[2026-03-16 15:55:15.56279] [27716] [info] Listening at "http://*:8080"
Web application available at http://127.0.0.1:8080
[2026-03-16 15:55:50.81445] [27716] [trace] [1ODKO9_D-nZZ] GET "/"
[2026-03-16 15:55:50.81945] [27716] [trace] [1ODKO9_D-nZZ] Routing to a callback
[2026-03-16 15:55:50.82339] [27716] [trace] [1ODKO9_D-nZZ] Rendering template "index.html.ep" from DATA section
[2026-03-16 15:55:50.82998] [27716] [trace] [1ODKO9_D-nZZ] 200 OK (0.015422s, 64.842/s)
[2026-03-16 15:55:51.40533] [27716] [trace] [ThnOL6K5Pt-k] GET "/title"
[2026-03-16 15:55:51.40978] [27716] [trace] [ThnOL6K5Pt-k] Routing to a callback
[2026-03-16 15:55:51.41264] [27716] [trace] [ThnOL6K5Pt-k] 101 Switching Protocols (0.00707s, 141.443/s)

En la página se verá el nombre de "Wikipedia".

Hagamos algo más complicado. Crear una aplicación que reciba peticiones y responda dinámicamente. Esto con ayuda de los WebSockets.

web_sockets.pl

use Mojolicious::Lite -signatures;

# Ruta normal para probar
get '/' => sub ($c) {
  $c->render(template => 'index');
};

# Endpoint WebSocket
websocket '/echo' => sub ($c) {
  $c->on(message => sub ($c, $msg) {
    # Responde con el mismo mensaje recibido
    $c->send("Servidor recibió: $msg");
  });
};

app->start;

__DATA__

@@ index.html.ep
<!DOCTYPE html>
<html>
  <head><title>Codemonkey Junior WebSocket con Mojolicious</title></head>
  <body>
    <h1>WebSocket con Mojolicious</h1>
    <script>
      // Conectar al servidor WebSocket
      const ws = new WebSocket('<%= url_for("echo")->to_abs %>');
      
      ws.onopen = function() {
        ws.send("¡Hola desde el cliente!");
      };
      
      ws.onmessage = function(event) {
        document.body.innerHTML += "<p>" + event.data + "</p>";
      };
    </script>
  </body>
</html>

Ejecutamos:

$ morbo web_sockets.pl

Abrimos un navegador en la ruta: http://127.0.0.1:3000/

Salida:

Web application available at http://127.0.0.1:3000
[2026-03-16 16:16:20.73121] [-15804] [trace] [2NKo74iWOXU_] GET "/"
[2026-03-16 16:16:20.73267] [-15804] [trace] [2NKo74iWOXU_] Routing to a callback
[2026-03-16 16:16:20.73900] [-15804] [trace] [2NKo74iWOXU_] Rendering template "index.html.ep" from DATA section
[2026-03-16 16:16:20.74582] [-15804] [trace] [2NKo74iWOXU_] 200 OK (0.014579s, 68.592/s)
[2026-03-16 16:16:21.61504] [-15804] [trace] [u4UBFpSvNxLo] GET "/echo"
[2026-03-16 16:16:21.61669] [-15804] [trace] [u4UBFpSvNxLo] Routing to a callback
[2026-03-16 16:16:21.61922] [-15804] [trace] [u4UBFpSvNxLo] 101 Switching Protocols (0.004105s, 243.605/s)

Se abrirá una página web con el mensaje:

WebSocket con Mojolicious
Servidor recibió: ¡Hola desde el cliente!

Mojolicious permite construir aplicaciones más complejas: broadcasting a múltiples clientes, integración con Minion para tareas en segundo plano, o extracción de datos en tiempo real desde APIs externas.

Estos son solo ejemplos básicos de uso de WebSockets y Mojolicious.

En próximas entregas veremos esto más a fondo.

Enlaces:

https://mojolicious.org/
https://mojolicious.io/

domingo, 1 de junio de 2025

Dancer2: un framework web para Perl

Dancer2 es el framework web ligero de nueva generación para Perl. Esta herramienta proporciona una interfaz CLI atractiva y fácilmente extensible.

Veremos cómo instalarlo y crear un ejemplo sencillo.

Instalación de Dancer2

Abre una terminal y escribe esto:

$ cpan

Entrarás a CPAN, ahora instalamos Dancer2:

cpan> i Dancer2

Comenzará el proceso de descarga e instalación. Esperamos un poco (pueden ser algunos minutos).

Cuando finalice verificamos la instalación:

$ dancer2 version

Obtener ayuda:

$ dancer2 --help

Para crear un proyecto:

$ dancer2 gen -a MyWeb::App

Esto te creará un proyecto web con Dancer2.

Nos ubicamos en el directorio creado y ejecutamos la aplicación:

$ cd MyWeb-App
$ plackup -r bin/app.psgi

Abrimos un navegador en la siguiente dirección:

https://0.0.0.0:5000

Ahora crearemos un sencillo programa web sin la necesidad de crear un proyecto completo.

Un Hola, mundo con Dancer2

Creamos un sencillo script para el clásico "Hola, mundo".

dancr.pl

#!/usr/bin/env perl
use Dancer2;
get '/' => sub {
    return 'Hola, mundo con Dancer2';
};
start;

Ejecutamos el script:

$ perl dancr.pl

Abrimos un navegador en la dirección:

http://localhost:3000/

¡Hemos creado nuestra primera aplicación con Dancer2!

continuaremos con este tema en próximas entregas.

Enlaces:

https://perldancer.org/
https://medium.com/lets-fill-the-gap/dancer2-introduction-and-installation-8444079355fd

sábado, 26 de abril de 2025

Creando una aplicación web para calcular el IMC con Mojolicious

En una entrega pasada vimos cómo crear una aplicación web para calcular el IMC de una persona usando Django Framework. Esta vez lo haremos usando Mojolicious, un framework ligero para Perl.

Creando la aplicación web

Requisitos:

  1. Tener instalado Perl en la última versión. 
  2. Instalar Mojolicious.

¿Qué haremos?

  1. Crear un solo programa, el cual nombraremos ``imc.pl``. 
  2. Crear la lógica para obtener los datos: nombre, edad, peso y talla. 
  3. Crear la lógica para obtener el IMC (peso / (talla**2)). 
  4. Crear las vistas: formulario y resultado.

Si no tenemos instalado Mojolicious, lo podemos instalar así:

$ cpan
cpan> install Mojolicious

1. Creamos el programa ``imc.pl`` (Linux o Windows).

Linux:

$ touch imc.pl

Windows:

$ start notepad imc.pl

2. Debemos obtener los datos del formulario. Para ello Mojolicious nos permitirá incrustrar código HTML desde el mismo programa Perl ``imc.pl``. Los llamados layaouts.

__DATA__

@@ formulario.html.ep
<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>IMC Generator</title>
    <style>
        body { font-family: Arial, sans-serif; text-align: center; }
        .container { max-width: 600px; margin: 0 auto; padding: 20px; }
        .form-group { margin-bottom: 15px; }
        input[type="text"], input[type="number"] { padding: 10px; width: 200px; }
        button { padding: 10px 20px; background-color: #4CAF50; color: white; border: none; cursor: pointer; }
        button:hover { background-color: #45a049; }
        .orange {
            color: #ff6200;
        }
        .green{
            color:rgb(13, 207, 55);;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1> <span class ="orange">IMC </span> <span class ="green">Generator</span></h1>
        <form method="POST" action="/">
            <div class="form-group">
                <label for="nombre">Nombre:</label><br>
                <input type="text" id="nombre" name="nombre" required>
            </div>
            <div class="form-group">
                <label for="edad">Edad:</label><br>
                <input type="number" id="edad" name="edad" required>
            </div>
            <div class="form-group">
                <label for="peso">Peso (kg):</label><br>
                <input type="number" step="0.1" id="peso" name="peso" required>
            </div>
            <div class="form-group">
                <label for="talla">Talla (m):</label><br>
                <input type="number" step="0.01" id="talla" name="talla" required>
            </div>
            <button type="submit">Aceptar</button>
        </form>
    </div>
</body>
</html>

Este será el formulario para la entrada de datos. Ahora crearemos la lógica una vez que obtenemos los datos (nombre, edad, peso y talla).

#!/usr/bin/env perl
use Mojolicious::Lite -signatures;

# Ruta para el formulario (GET)
get '/' => sub ($c) {
    $c->render(template => 'formulario');
};

# Ruta para procesar el formulario y mostrar resultados (POST)
post '/' => sub ($c) {
    # Obtener datos del formulario
    my $nombre = $c->param('nombre');
    my $edad   = $c->param('edad') || 0;
    my $peso   = $c->param('peso') || 0;
    my $talla  = $c->param('talla') || 0;

    # Calcular IMC
    my $imc = $talla > 0 ? $peso / ($talla * $talla) : 0;

    # Diagnóstico y recomendaciones
    my ($diagnostico, $recomendaciones);
    if ($imc < 18.5) {
        $diagnostico = "Peso bajo";
        $recomendaciones = "Necesita ayuda médica. Considere aumentar su ingesta calórica.";
    } elsif ($imc >= 18.5 && $imc <= 24.9) {
        $diagnostico = "Peso normal";
        $recomendaciones = "No necesita ayuda médica. Solo necesita seguir alimentándose bien y hacer ejercicio.";
    } elsif ($imc >= 25 && $imc <= 29.9) {
        $diagnostico = "Sobrepeso";
        $recomendaciones = "Necesita ayuda médica. Considere una dieta balanceada y ejercicio regular.";
    } else {
        $diagnostico = "Obesidad";
        $recomendaciones = "Necesita ayuda médica urgente. Consulte a un especialista.";
    }

    # Calcular peso ideal y talla ideal (IMC ideal = 22)
    my $imc_ideal = 22;
    my $peso_ideal = $imc_ideal * ($talla * $talla);
    my $talla_ideal = $peso > 0 ? sqrt($peso / $imc_ideal) : 0;

    # Renderizar la página de resultados
    $c->render(
        template        => 'resultado',
        nombre          => $nombre,
        edad            => $edad,
        peso            => $peso,
        talla           => $talla,
        imc             => sprintf("%.2f", $imc),
        diagnostico     => $diagnostico,
        recomendaciones => $recomendaciones,
        peso_ideal      => sprintf("%.2f", $peso_ideal),
        talla_ideal     => sprintf("%.2f", $talla_ideal),
    );
};

Por último la página de resultados.

@@ resultado.html.ep
<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Resultado IMC</title>
    <style>
        body { font-family: Arial, sans-serif; text-align: center; }
        .container { max-width: 600px; margin: 0 auto; padding: 20px; }
        .result { margin-top: 20px; padding: 20px; border: 1px solid #ccc; border-radius: 5px; }
        .result h2 { color: #4CAF50; }
        button { padding: 10px 20px; background-color: #4CAF50; color: white; border: none; cursor: pointer; }
        button:hover { background-color: #45a049; }
        .orange {
            color: #ff6200;
        }
        .green{
            color:rgb(13, 207, 55);;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1> <span class ="orange">IMC </span> <span class ="green">Generator</span></h1>
        <div class="result">
            <p><strong>Nombre:</strong> <%= $nombre %></p>
            <p><strong>Edad:</strong> <%= $edad %></p>
            <p><strong>Peso:</strong> <%= $peso %> kg</p>
            <p><strong>Talla:</strong> <%= $talla %> m</p>
            <h2>IMC: <%= $imc %></h2>
            <p><strong>Diagnóstico:</strong> <%= $diagnostico %></p>
            <p><strong>Recomendaciones:</strong> <%= $recomendaciones %></p>
            <p><strong>Su peso ideal debe ser:</strong> <%= $peso_ideal %> kg</p>
            <p><strong>Su talla ideal debe ser:</strong> <%= $talla_ideal %> m</p>
        </div>
        <a href="/"><button>Aceptar</button></a>
    </div>
</body>
</html>

Código completo:

imc.pl

#!/usr/bin/env perl
use Mojolicious::Lite -signatures;

# Ruta para el formulario (GET)
get '/' => sub ($c) {
    $c->render(template => 'formulario');
};

# Ruta para procesar el formulario y mostrar resultados (POST)
post '/' => sub ($c) {
    # Obtener datos del formulario
    my $nombre = $c->param('nombre');
    my $edad   = $c->param('edad') || 0;
    my $peso   = $c->param('peso') || 0;
    my $talla  = $c->param('talla') || 0;

    # Calcular IMC
    my $imc = $talla > 0 ? $peso / ($talla * $talla) : 0;

    # Diagnóstico y recomendaciones
    my ($diagnostico, $recomendaciones);
    if ($imc < 18.5) {
        $diagnostico = "Peso bajo";
        $recomendaciones = "Necesita ayuda médica. Considere aumentar su ingesta calórica.";
    } elsif ($imc >= 18.5 && $imc <= 24.9) {
        $diagnostico = "Peso normal";
        $recomendaciones = "No necesita ayuda médica. Solo necesita seguir alimentándose bien y hacer ejercicio.";
    } elsif ($imc >= 25 && $imc <= 29.9) {
        $diagnostico = "Sobrepeso";
        $recomendaciones = "Necesita ayuda médica. Considere una dieta balanceada y ejercicio regular.";
    } else {
        $diagnostico = "Obesidad";
        $recomendaciones = "Necesita ayuda médica urgente. Consulte a un especialista.";
    }

    # Calcular peso ideal y talla ideal (IMC ideal = 22)
    my $imc_ideal = 22;
    my $peso_ideal = $imc_ideal * ($talla * $talla);
    my $talla_ideal = $peso > 0 ? sqrt($peso / $imc_ideal) : 0;

    # Renderizar la página de resultados
    $c->render(
        template        => 'resultado',
        nombre          => $nombre,
        edad            => $edad,
        peso            => $peso,
        talla           => $talla,
        imc             => sprintf("%.2f", $imc),
        diagnostico     => $diagnostico,
        recomendaciones => $recomendaciones,
        peso_ideal      => sprintf("%.2f", $peso_ideal),
        talla_ideal     => sprintf("%.2f", $talla_ideal),
    );
};

# Iniciar la aplicación
app->start;

__DATA__

@@ formulario.html.ep
<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>IMC Generator</title>
    <style>
        body { font-family: Arial, sans-serif; text-align: center; }
        .container { max-width: 600px; margin: 0 auto; padding: 20px; }
        .form-group { margin-bottom: 15px; }
        input[type="text"], input[type="number"] { padding: 10px; width: 200px; }
        button { padding: 10px 20px; background-color: #4CAF50; color: white; border: none; cursor: pointer; }
        button:hover { background-color: #45a049; }
        .orange {
            color: #ff6200;
        }
        .green{
            color:rgb(13, 207, 55);;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1> <span class ="orange">IMC </span> <span class ="green">Generator</span></h1>
        <form method="POST" action="/">
            <div class="form-group">
                <label for="nombre">Nombre:</label><br>
                <input type="text" id="nombre" name="nombre" required>
            </div>
            <div class="form-group">
                <label for="edad">Edad:</label><br>
                <input type="number" id="edad" name="edad" required>
            </div>
            <div class="form-group">
                <label for="peso">Peso (kg):</label><br>
                <input type="number" step="0.1" id="peso" name="peso" required>
            </div>
            <div class="form-group">
                <label for="talla">Talla (m):</label><br>
                <input type="number" step="0.01" id="talla" name="talla" required>
            </div>
            <button type="submit">Aceptar</button>
        </form>
    </div>
</body>
</html>

@@ resultado.html.ep
<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Resultado IMC</title>
    <style>
        body { font-family: Arial, sans-serif; text-align: center; }
        .container { max-width: 600px; margin: 0 auto; padding: 20px; }
        .result { margin-top: 20px; padding: 20px; border: 1px solid #ccc; border-radius: 5px; }
        .result h2 { color: #4CAF50; }
        button { padding: 10px 20px; background-color: #4CAF50; color: white; border: none; cursor: pointer; }
        button:hover { background-color: #45a049; }
        .orange {
            color: #ff6200;
        }
        .green{
            color:rgb(13, 207, 55);;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1> <span class ="orange">IMC </span> <span class ="green">Generator</span></h1>
        <div class="result">
            <p><strong>Nombre:</strong> <%= $nombre %></p>
            <p><strong>Edad:</strong> <%= $edad %></p>
            <p><strong>Peso:</strong> <%= $peso %> kg</p>
            <p><strong>Talla:</strong> <%= $talla %> m</p>
            <h2>IMC: <%= $imc %></h2>
            <p><strong>Diagnóstico:</strong> <%= $diagnostico %></p>
            <p><strong>Recomendaciones:</strong> <%= $recomendaciones %></p>
            <p><strong>Su peso ideal debe ser:</strong> <%= $peso_ideal %> kg</p>
            <p><strong>Su talla ideal debe ser:</strong> <%= $talla_ideal %> m</p>
        </div>
        <a href="/"><button>Aceptar</button></a>
    </div>
</body>
</html>

Ejecución del programa:

$ morbo imc.pl

Abrimos el navegador en la ruta:

http://127.0.0.1:3000/

¡Con esto habremos habremos creado nuestra aplicación webb con Mojolicious!

La aplicación se verá así:

Introducimos los datos:

Obtenemos los resultados:

Mojolicious nos permite crear aplicaciones web de una manera más sencilla a lo que otros frameworks no.

En esta aplicación hemos visto algunas de sus características, como el permitir incrustrar código HTML (con extensión *html.ep) como en PHP.

Más sobre este framework en próximas entregas.

Enlaces:

https://mojolicious.org/
https://codemonkeyjunior.blogspot.com/2025/04/mojolicious-un-framework-para-perl.html
https://codemonkeyjunior.blogspot.com/2025/04/creando-una-aplicacion-web-para.html

Jai un lenguaje de programación inspirado en C++

Hoy hablaremos de un nuevo lenguaje de programación llamado Jai . Se trata de un lenguaje de programación que está desarrolland...

Etiquetas

Archivo del blog