martes, 3 de febrero de 2015

Perl es divertido

Se me ocurrió buscar si se podía usar utf8 en el nombre de las subs en perl. Resulta que sí.

use strict; use warnings;
use feature 'say';
use utf8;

sub ña() {
    say "Soy una eñe";
}
sub ᐁ() {
    say "Soy un triángulo";
}

ña;
ᐁ;
Resulta en:

Soy una eñe
Soy un triángulo

Es tarde, pero se pueden hacer miles de dibujitos con estos caracteres. Perl siempre tuvo eso de poder hacer pavadas como esas (perl golf, dark perl) así que no es nada nuevo.

Les dejo un gato, que mira lo que hice y se pregunta porqué hago esto.








domingo, 4 de enero de 2015

Aventuras con mi teclado nuevo II

Sigo con mi teclado nuevo. Resulta que el teclado de mi notebook está en español "latam" y este nuevo está en "es". Quiero que cada uno esté en el idioma que le corresponde. Sí, así de cabeza dura soy.

Para eso se usa "setxkbmap":

 setxkbmap -device 3 latam
 setxkbmap -device 11 es

¿Cual es cual? Ese número de device se encuentra con xinput:

  xinput -list
⎡ Virtual core pointer                          id=2    [master pointer  (3)]
⎜   ↳ Virtual core XTEST pointer                id=4    [slave  pointer  (2)]
⎜   ↳ SynPS/2 Synaptics TouchPad                id=14   [slave  pointer  (2)]
⎣ Virtual core keyboard                         id=3    [master keyboard (2)]
    ↳ Virtual core XTEST keyboard               id=5    [slave  keyboard (3)]
    ↳ Power Button                              id=6    [slave  keyboard (3)]
    ↳ Video Bus                                 id=7    [slave  keyboard (3)]
    ↳ Power Button                              id=8    [slave  keyboard (3)]
    ↳ Sleep Button                              id=9    [slave  keyboard (3)]
    ↳ WebCam SCB-1900N                          id=10   [slave  keyboard (3)]
    ↳ SINO WEALTH USB KEYBOARD                  id=11   [slave  keyboard (3)]
    ↳ SINO WEALTH USB KEYBOARD                  id=12   [slave  keyboard (3)]
    ↳ AT Translated Set 2 keyboard              id=13   [slave  keyboard (3)]

Hermoso. Salvo que es bastante molesto, porque uno está acostumbrado a encontrar el acento o los corchetes en un lugar. Así que no sé qué voy a hacer.

Aventuras con mi teclado nuevo I

Me compré un teclado (simil) mecánico, con backlight (luz de fondo). Para prenderlo o apagarlo se aprieta "Scroll lock".

NOTA: Extrañamente esa tecla está escrita con "Bloq Num", y hay otra tecla con lo mismo en el pad numérico. "Block Num" y "Scroll Lock" no es lo mismo. 

Pero cuando uno lo enchufa a una computadora que tiene linux, ¡la luz no se prende! Investigué un poco pero no pude encontrar porqué. Sólo encontré que hay una forma de prender los leds de un teclado con un comando: uno puede prender de a uno o todos a la vez:

# Prende el led 1. No se sabe qué led es. ¿Cambiará de teclado en teclado?
# En el mío no cambia nada, pero sería así:
xset led 1


# Para apagarlo.
xset -led 1

# Para prender todo
xset led

# Para apagar todo
xset -led

 Este teclado tiene solo un led, el de 3 (Scroll Lock). Como también se puede apagar y prender con el nombre de la tecla, hago eso.
xset -led named "Scroll Lock"
xset led  named "Scroll Lock"

Sin embargo ahora tengo un comando, pero yo quiero poder apretar Scroll Lock y que se prenda y apague. En KDE se puede configurar que al apretar una tecla ejecute algo, asì que hice un script para que cambie el estado del led según esté.

#/bin/bash
# Este script prende o apaga (debería llamarse "lapegue") la luz del
# fondo del teclado "Dragon gaming keyboard" que me compré en enero/15.
# Es un teclado pseudo-mecánico.

# Para debug (al principio costó que funcionara con la tecla Bloq Num)
# exec 1>> /tmp/qq
# exec 2>> /tmp/qq
# 0 si lo encontró, 1 si no lo encontró.
xset q | grep "Scroll Lock: on" 
OUT=$?
# echo $OUT

if ( [ $OUT -eq 0 ] )
then
    # Está prendido.
    xset -led named "Scroll Lock"
else
    # Apagado.
    xset led named "Scroll Lock"
fi

xset es el comando que da información sobre el estado de los leds:

  xset q
Keyboard Control:
  auto repeat:  on    key click percent:  100    LED mask:  0000003c
  XKB indicators:
    00: Caps Lock:   off    01: Num Lock:    off    02: Scroll Lock: on
    03: Compose:     off    04: Kana:        off    05: Sleep:       off
    06: Suspend:     off    07: Mute:        off    08: Misc:        off
    09: Mail:        off    10: Charging:    off    11: Shift Lock:  off
    12: Group 2:     off    13: Mouse Keys:  off
[...]

Si dice "Scroll Lock: on" quiere decir que la luz está prendida.

Finalmente, lo agregamos a la configuración de KDE. Primero ir a System Settings -> Shortcut and Gestures -> Custom Shorcuts. Luego crear una nueva entrada (yo le puse "keyboard_backlight")  con Edit -> New -> Global -> Command/URL y poner ahí el nombre del script de más arriba.



domingo, 10 de agosto de 2014

Tip: Cómo agregar texto a una imagen con ImageMagick

Hola!

    Necesito agregar la fecha a una imagen. Algún día les contaré qué estoy haciendo :P



    Tengo esta imagen, saca de The Humble Yogini - Observations from the realm of Samsara:








Y con este comando, ¡pasen y vean! , le agregamos tóscamente la fecha:
 /usr/bin/convert \
        Computer_color_spectrum.jpg \
        -pointsize 38 -font URW-Bookman-L-Light \
        -annotate +80+100 "$(date --rfc-3339=date)"  \
         /tmp/colores.gif
 


Y quedó así:



         Tada!





Saludos!
 -- Diego.



sábado, 9 de agosto de 2014

Cómo sacar algunos sigils ($@%&), parte 4

Esto es... no sé qué es. Es una chanchada. Es otro forma de sacar sigils. No creo que deba usarse, pero acá está:

Cuando uno usa objetos en perl (sean hechos con Moo(se) o de cualquier otra forma) (pero hay que usar Moo(se) :) ), hace algo así:

use MiClase;
my $objeto = MiClase->new();

Y después usamos los atributos y métodos de $objeto. Supongamos que sirve para guardar frases célebres:

use Quote;
my $q = Quote->new();
$q->set_phrase("Un problema imaginario es la raíz de
                               todo pensamiento negativo");

print "La frase es: " . $q->get_phrase . "\n";

Con esto podemos tener (instanciar) un montón de objetos "Quote".

my $q = Quote->new();
my $otra_q = Quote->new()
my $otro = Quote->new()
Pero también podríamos evitar los sigils, no instanciando (creando) un objeto, sino usando la clase. Esto es horrible, y no debe hacerse, pero WTH, lo hago igual :)

 use Quote;
Quote->set_phrase("Un problema imaginario es la raíz de
                                    todo pensamiento negativo
");
print Quote->get_phrase() . "\n";
 Este es el código de Quote.pm

package Quote;

use strict;

our $self;

# Cuando se llama a la clase directamente, el primer argumento
# es justamente el nombre de la clase. No nos interesa.
sub set_phrase {
  my $class = shift;
  my $phrase = shift;
  $self->{phrase} = $phrase;
}

sub get_phrase {
  my $class = shift;
  return $self->{phrase};
}

1;
Sinceramente, no sé cuán horrible es esto. Qué efectos secundarios tendrá. Le encontré por lo menos una, que es que la clase/objeto es global. Osea, si le ponés un valor a la frase, lo va a tener dentro de toda sub. Supongo que hay alguna forma de cambiarlo. Les dejo un gato:






domingo, 3 de agosto de 2014

Pequeño ejemplo de crear archivos ical con Perl

¡Hola de nuevo!

    Estuve trabajando en un programa que en una parte guarda eventos en un archivo ical. Me costó un poco encontrar un buen módulo. El mejor y más sencillo es Tie::iCal, aunque verán que tiene un bug al final.

sub guardar_evento {
    # segundos: tiempo que falta para el final del evento
    # contenido: la descripción del evento (ej "Reunión con Pepe")
    my ($segundos, $contenido) = @_;
    my %my_events;
    my $calfile = "/.mycalendar.ics";
    tie %my_events, 'Tie::iCal', $calfile or die "Failed to tie file!\n";

    # Summary no puede tener enter, así que lo cambio por \n
    $contenido =~ s/\n/\\n/gs;



    # Cada evento es una entrada, y c/u tiene un UID
    my $uid = time();
    $my_events{$uid} = [
    'VEVENT',
             {
              'SUMMARY' => $contenido,
              'DTSTART' => secs_to_ical_date(0),
              'DTEND'   => secs_to_ical_date($segundos),
             }
    ];
    untie %my_events;
}



# Esta func agrega $secs segundos a la fecha/hora actual
# y lo devuevle en el formato para iCal
sub secs_to_ical_date {
    my ($secs) = @_;


  
    # Usamos Time::Piece, que viene con Perl y nos lo hace más facil
    my $now = mk_time_piece_now();
    $now += $secs;
    my $date = $now->strftime( "%Y%m%d" )  . "T" .
               $now->strftime( "%H%M00" ) . "Z";
    return $date;
}

sub mk_time_piece_now {
      # Esto pasa porque el objeto Time::Piece que resulta de

      # localtime tiene mal el timezone. Así que lo hago string,
      # y lo vuelvo a hacer objeto. Grrrr.
      my $now        = localtime;
      my $now_string = $now->strftime("%d-%m-%Y %H:%M");
         $now        = Time::Piece->strptime($now_string, 

                                            "%d-%m-%Y %H:%M");
      return $now;
}



Pero resulta que el archivo iCal queda mal hecho, así que este pedazo de código lo arregla. Reporté el bug acá.

open( my $ical, "<", ".mycalendar.ics") or die $!;

my $head = "";
foreach my $n (1, 2, 3) {
     my $temp = <$ical>;
     $head = $head . $temp;
}


my $body = "";
while ( <$ical> ) {
    next if ( /BEGIN:VCALENDAR/ );
    next if ( /VERSION:/ );
    next if ( /PRODID:/ );
    next if ( /END:VCALENDAR/ );
    $body = $body . $_;
}

my $foot = "END:VCALENDAR\n";


# Y escribirlo a un archivo.
use File::Slurp;
write_file( ".mycalendar_fixed.ics", $head . $body . $foot );



Dos bugs. No está nada bien :(

Les dejo un conejo.



Saludos!
-- Diego



Slides sobre Moose, la implementación moderna de OO de perl

estoy con fiaca de escribir :P

Diapositivas, o tutorial con pocas letras sobre el sistema de OO de perl (el nuevo), con todos los roles, mixins y magia que hay en el mundo de la programación OO.


Les dejo un camello:


Algo más quería postear, pero no me acuerdo...