2007-12-30

Dual head en mi notebook

Estoy muy contento de como quedó la configuración de la pantalla de mi Inspiron 1520.

Después de un toque de googleo, encontré un post donde explican cómo configurar una notebook con placa Intel para que soporte 2 monitores (el de la notebook y otro más) en KUbuntu Gutsy. Así que seguí los pasos (que son bastante simples) y los retoqué un bati-toque (santas redundancias batman) para que se configure solo.

Primero agregué a la subsección "Screen"/"Display" del archivo la entrada:

virtual         2560    1024

La onda de esta entrada es que el virtual desktop alcance para los 2 monitores.

Después me agregué en $HOME/bin 2 scripts. Uno para activar el segundo monitor y configurarlo bien y otro para desactivarlo. El que activa y configura el segundo monitor (dual-head) es:
#!/usr/bin/env bash

xrandr --output VGA --auto
xrandr --output VGA --right-of LVDS


El que la apaga es:
#!/usr/bin/env bash

xrandr --output VGA --off


Por último, linkié en ~/.kde/Autostart el script dual-head, así se setea automágicamente la dualidad onda-monitor. Si el monitor no está enchufado, el script no hace nada, así que lo dejé así:
ln -s ../../bin/dual-head


Así que ahora tengo todo listo y cuando estoy en casa puedo usar mi otro monitor también.

2007-12-24

Papá Noel

Ayer a la noche hice de Papá Noel en el complejo de departamentos en el que vivo. Fue un quilombo de niñ@s y adult@s. Impresionante el efecto que genera el disfraz de Papá Noel en la gente. L@s chic@s se me quedaban mirando (se quedarían preguntándose, ¿es de verdad?). En el evento repartí bolsitas con regalitos tontos para l@s chic@s y recibí algunas cartitas. Entre las cartas que recibí está la de mi sobrina.


Y acá está una foto con ella (que nunca supo que Papá Noel era yo) y de fondo el batifondo (santas redundancias batman) del evento.

La verdad, lo disfruté mucho.

2007-12-17

PHP es KK. Un ejemplo práctico

Hoy mi amigo Ernesto Alvarez me mostró un pequeñísimo ejemplo de porqué PHP es una mierda. La semántica del lenguaje deja muuuucho que desear.

El programa:

<?php
echo count == 0;# . "\n";
?>


Muestra "1" en la salida por standard output.

En cambio si dejamos el enter comentado no muestra nada. Este es el código que no muestra nada:

<?php
echo count == 0 . "\n";
?>


Bueno, una cosa más para hacer leña del árbol caído.
Hasta la próxima, amigos.

Update: Escribí una segunda parte de esto en mi artículo Si php es KK, ¿por qué lo usan tanto?.

2007-11-28

51 x 10^9 (parte 2)

En mi mi último post, mostré un problema que usan en ITA para reclutar gente. Parece que anda mal porque el resultado que encuentra no coincide con el fin de un número, como dice en el enunciado. Pero como me quedé desvelado una noche haciendolo, les mandé un mail con mi solución. Mientras tanto aprovecho y les pregunto a ustedes.

¿Le ven algún quilombo al código de abajo?


#!/usr/bin/env ruby

class Result
attr_accessor :letters_advanced
attr_accessor :letters_missing
attr_accessor :sum
attr_accessor :number
attr_accessor :name

def initialize(letters_missing=0)
self.letters_missing = letters_missing
self.sum = 0
self.letters_advanced = 0
self.number = -1 # not set
end

def << (other_result)
self.letters_advanced += other_result.letters_advanced
self.sum += other_result.sum
self.letters_missing -= other_result.letters_advanced
self.number = other_result.number
self.name = other_result.name
end

def to_s
string = "name:#{name} - number:#{number} - " +
"letters_advanced:#{letters_advanced} - " +
"letters_missing:#{letters_missing} - sum:#{sum}"
string += " - letter:#{name[name.length-1+letters_missing,1]}" if letters_missing <= 0
end
end

class Block

attr_reader :value
attr_reader :name
attr_accessor :next_block
attr_reader :position # 0 for ones, 1 for thousands, 2 for millions

def initialize( name, number, position )
@name = name
@value = number * (1000 ** position)
@position = position
end

# Inserts a block somewhere after this block, hopefully close (if not, takes a long time)
def insert_block(new_block)
before = self
after = self.next_block
while( after != nil && new_block.name > after.name )
before = after
after = before.next_block
end
before.next_block = new_block
new_block.next_block = after
end

def advance(min_position, max_position)
current = self.next_block
while !current.nil? && !current.position.between?(min_position, max_position)
current = current.next_block
end
current
end

ONES = [ "", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" ]
TEENS = ["ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen",
"seventeen", "eighteen", "nineteen" ]
ORIG_TENS = [ "twenty", "thirty", "fourty", "fifty", "sixty", "seventy", "eighty", "ninety" ]

tens = Array.new
ONES.each { |n| tens << n }
TEENS.each { |n| tens << n }
ORIG_TENS.each do
|ten|
ONES.each do
|one|
tens << ten + one
end
end

TENS = tens

HUNDREDS = ONES.map do
|hundred|
root = hundred == "" ? "" : hundred + "hundred"
numbers = tens.map do
|ten|
root + ten
end
numbers
end.flatten

number = 0
NAMED_HUNDREDS = HUNDREDS.map do
|name|
value = { :number => number, :name => name }
number += 1
value
end.sort_by { |pair| pair[:name] }.reverse

last = nil
NAMED_HUNDREDS.each do
|pair|
new = Block.new(pair[:name], pair[:number], 0)
new.next_block = last
last = new
end

@last = last.next_block # Ignore zero

#Add higher level blocks (thousand and millions)
current = last
while( current != nil )
if current.position == 0 then
current.insert_block( Block.new(current.name + "thowsand", current.value, 1) )
current.insert_block( Block.new(current.name + "million", current.value, 2) )
end

current = current.next_block
end

def self.first( position=0 )
first = @last
while (first.position != position)
first = first.next
end
first
end
end

class Number

def initialize( pos2, pos1, pos0 )
@blocks = [pos0, pos1, pos2]
end

def name
@blocks.reverse.inject("") do
|acum, block|
acum += block ? block.name : ""
end
end

def value
@blocks.inject(0) do
|acum, block|
acum += block ? block.value : 0
end
end

def description
r = Result.new
r.letters_advanced = self.name.length
r.name = self.name
r.number = r.sum = self.value
r
end

def next_number(min_pos=0)
max_pos = min_pos + 1
while @blocks[max_pos].nil? && max_pos < 3
max_pos += 1
end
max_pos -= 1
new_block = @blocks[min_pos] ? @blocks[min_pos].advance(min_pos, max_pos) : Block.first(min_pos)
@blocks[min_pos] = nil
if (new_block) then
@blocks[new_block.position] = new_block
else #carry
self.next_number(min_pos + 1)
end
self
end

unit_letter_count = 0
unit_accumulated_values = 0
block = Block.first(0)
while( block )
unit_letter_count += block.name.length
unit_accumulated_values += block.value
block = block.advance(0,0)
end
UNIT_LETTER_COUNT = unit_letter_count
UNIT_ACCUMULATED_VALUES = unit_accumulated_values

def step(result)

if (@blocks[1] && !@blocks[0])
big_step_char_count = self.name.length * 1000 + UNIT_LETTER_COUNT
if big_step_char_count < result.letters_missing then
step_result = Result.new
step_result.letters_advanced = big_step_char_count
step_result.number = step_result.sum = self.value * 1000 + UNIT_ACCUMULATED_VALUES
result << step_result
self.next_number(1)
return
end
end
# Big step is not taken
result << self.description
self.next_number
end

def self.first
self.new( nil, nil, Block.first )
end

def self.result( letter_position)
result = Result.new(position)
number = Number.first
while( result.letters_missing > 0 )
result << number.description
number=number.next_number
end
result
end

end


position = ARGV[0].to_i
result = Result.new(position)
number = Number.first
count = 0
while( result.letters_missing > 0 )
number.step(result)

count += 1
if (count % 100000) == 0 then
puts "Partial result"
p result
end
end

puts "Final result"
puts result

2007-11-25

51 x 10^9

Como estuve con un poquito de tiempo libre me puse a programar un toque este sábado a la noche (sí que soy divertido :p). Y encontré un problemita intereseante en el blog de una .com. El problema es el mismo que proponen en ITA para tomarte como programador.

El mismo consiste en saber cuál es la letra número 51 x 10^9 (o sea 51000000000) de la secuencia de agarrar todos los números entre 1 y 1000000000 y transformarlos en letras, saber a que número pertenece y cuanto vale la suma de todos los números por los que pasaste para llegar a esa letra desde el principio. La solución del problema es un bardo, así que no lo hice todo, pero escribí un programa para obtener la letra en la posición x en la secuencia de números que va del 1 al 1000, a qué número pertenece y cuál fue la suma acumulada hasta ahí.

Acá les pongo a continuación el enunciado del problema:

"If the integers from 1 to 999,999,999 are written as words, sorted alphabetically, and concatenated, what is the 51 billionth letter?"

To be precise: if the integers from 1 to 999,999,999 are expressed in words (omitting spaces, 'and', and punctuation[1]), and sorted alphabetically so that the first six integers are

  • eight
  • eighteen
  • eighteenmillion
  • eighteenmillioneight
  • eighteenmillioneighteen
  • eighteenmillioneighteenthousand
and the last is
  • twothousandtwohundredtwo
then reading top to bottom, left to right, the 28th letter completes the spelling of the integer "eighteenmillion".

The 51 billionth letter also completes the spelling of an integer. Which one, and what is the sum of all the integers to that point?

[1] For example, 911,610,034 is written "ninehundredelevenmillionsixhundredtenthousandthirtyfour"; 500,000,000 is written "fivehundredmillion"; 1,709 is written "onethousandsevenhundrednine".

Y este es mi programa en ruby. Una generalización trivial para correrlo con los números que vayan desde 1 a 1000000000 requeriría (según estimo) unos 100GB de espacio libre en el disco rígido, varios días de tiempo de procesamiento para correr e implementar una rutina de external sorting. Pero me parece que los números tienen suficiente estructura como para cortar camino, así que si se me ocurre algo mejor lo postiaré por acá también.



#!/usr/bin/env ruby

class Result
attr_accessor :letters_advanced
attr_accessor :letters_missing
attr_accessor :sum
attr_accessor :number

def initialize(letters_missing=0)
self.letters_missing = letters_missing
self.sum = 0
self.letters_advanced = 0
self.number = -1 # not set
end

def << (other_result)
self.letters_advanced += other_result.letters_advanced
self.sum += other_result.sum
self.letters_missing -= other_result.letters_advanced
self.number = other_result.number
end
end

class Hundred

attr_reader :value
attr_reader :name
attr_reader :next_number

def initialize( name, value, next_number )
@name = name
@value = value
@next_number = next_number
end

def description
r = Result.new
r.letters_advanced = self.name.length
r.sum = self.value
r.number = self.value
r
end

ONES = [ "", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" ]
TEENS = ["ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen" ]
ORIG_TENS = [ "twenty", "thirty", "fourty", "fifty", "sixty", "seventy", "eighty", "ninety" ]

tens = Array.new
ONES.each { |n| tens << n }
TEENS.each { |n| tens << n }
ORIG_TENS.each do
|ten|
ONES.each do
|one|
tens << ten + one
end
end

TENS = tens

HUNDREDS = ONES.map do
|hundred|
root = hundred == "" ? "" : hundred + "hundred"
numbers = tens.map do
|ten|
root + ten
end
numbers
end.flatten

number = 0
NAMED_HUNDREDS = HUNDREDS.map do
|name|
value = { :number => number, :name => name }
number += 1
value
end.sort_by { |pair| pair[:name] }.reverse

last = nil
NAMED_HUNDREDS.each do
|pair|
last = Hundred.new(pair[:name], pair[:number], last)
end

@last = last

def self.first
@last
end
end

position = ARGV[0].to_i
result = Result.new(position)
number = Hundred.first
while( result.letters_missing > 0 )
result << number.description
number=number.next_number
end

p result

2007-11-18

Viaje boliviano

Mi cuñada está de viaje (tipo mochilera) por Bolivia desde junio. Éstas son las consecuencias del viaje, tal como lo relata en un mail:

"cerca de alli esta el ojo del inca, que es una fuente de aguas termales segun dicen con grandes propiedades curativas.... y creo que es lo uqe estoy necesitando en este momento porque no paro de tener problemas de salud.... nada grave no te preocupes, pero la verda es que me siento unav ieja tomando antibioticos, poniendome pomadas n diversos lugares del cuerpo, tomando toda clase de hierbas y yendo de medico en medico, a ver si alguna vez alguno la pega..... por suerte la quemadura ya cicatizo, pero tendre una enorme mancha en la pierna por el resto de mis dias.... de cualquier manera estoy probando con aloe vera y mayonesa, a ver si se borra un poco, pero por ahora no veo mucho resultado....

despues esta el tema del quiste, que creo que te habia contado, que me salio hace unos meses en el gluteo y me esta molestando por demas, ahora estoy probando con un nuevo antibiotico y si no funciona tendre que ir a un especialista porque eso si me dijeron que no lo deje pasar....
y de la selva me traje algo que parece ser un excema, cosa que nadie supo explicarme que es, pero todavia ono encuentro cura y no solo me duele sno que tengo la piel que pareciera pudrirse, justo detras de la rodilla....
por si fuera poco tengo parasitos que me hacen descomponerme cada dos por tres.... ahora estoy probando con gotitas de ajenjo y bardana que me regalo un español, el problema es que deberia continuar el tratamiento pero no encuentro esas hierbas por aqui......"

¿Sobrevivirá para traerme el charango que le pedí?

2007-11-08

¿Qué estudio?

Estoy con ganas de estudiar algo el año que viene (y quizás algunos más, o no). Mis opciones son bastante amplias, así que quería preguntarles que les parecen, si se les ocurre alguna otra, si alguna les parece que no vale la pena (por ejemplo, porque lo estudiaron y no les parece que lo vale) o si hay alguna de éstas que sea la posta. Es claro que no puedo estudiar todo esto, así que tengo que elegir.

Estas son las opciones que se me ocurrieron (sin ningún orden particular) y algunos pros y contras:

  • Lenguaje chino (¿mandarín?)
    • Pros: 1/6 del mundo lo habla. Tiene una forma re conceptual de definir las ideas.
    • Cons: mucha gente lo estudia. ¿No me puedo comunicar en inglés? Aparentemente es re-dificil
  • Lenguaje coreano
    • Pros: menos gente lo estudia. La comunidad coreana argentina es bastante grande.
    • Cons: menos gente lo habla.
  • Matemática
    • Pros: es perenne.
    • Cons: descolgado del mundo. Carrera exigente y larga.
  • Física
    • Pros: el mejor ejemplo de modelado que hay.
    • Cons: Carrera exigente y larga. ¿Hay gente más pedante que los físicos?
  • Algo relacionado con el diseño gráfico
    • Pros: Una de mis falencias más evidentes es la falta de criterio estético.
    • Cons: Una de mis falencias más evidentes es la falta de criterio estético.
  • Doctorado en computación
    • Pros: Seguir avanzando en el mismo camino.
    • Cons: Los doctorados son algo demasiado intensivo y no tengo forma de aguarlo (en las carreras de grado cursaría menos materias y listo).
Bueno, eso es todo.
Escucho ideas, sugerencias y críticas.

2007-10-26

El voto geek

El voto geek está complicado en estas elecciones.

Por un lado están los pingüinos K, que en su plataforma tienen Linux con KDE.

Por otro lado está UNA, representante de una gran tradición, el acrónimo recursivo.

Por lo tanto, el voto geek estará fuertemente polarizado. ¿A quién apoyaremos en estas elecciones?

PD: Si ya sé, estoy rompiendo la veda. Si quieren denúncienme al COMFER.
PD2: El voto geek puede o no estar correlacionado con el voto del resto de la gente.

2007-10-24

El botellón del dispenser

Hace un tiempo que estuve pensando en cómo explicar cuál es el mejor momento para hacer un refactoring, y cómo explicar cuál es el momento para hacer el refactoring, y cómo explicar cómo explicar cuál es el momento para hacer el refactoring....
Bueno, ustedes captan la idea.
Y esta es la explicación que elaboré.
Hacer un refactoring es como cambiar el botellón del dispenser de agua de la oficina.
¿Por qué?

  • No vas a ganar más plata por cambiar el bidón.
  • Generalmente cambiar el bidón es un dolor de huevos.
  • Pero peor es no cambiarlo (y quedar sediento).

Bueno, ¿y cuándo conviene cambiar un bidón del dispenser?
Definitivamente no cuando todavía queda agua en el mismo.

Tampoco es una buena idea cambiarlo después de que deje de salir agua del dispenser, porque cuando quieras sacar agua caliente va a estar tibia y cuando quieras sacar agua fría va a estar tibia.

¿Entonces cuándo hay que cambiarlo?
Cuando se vació el bidón, pero queda agua en el tanque que está adentro del dispenser (y las cañerías). Entonces no desperdiciamos agua y el agua sale fría y caliente cuando lo queremos.

Hacer refactorings es algo parecido. Hacer un refactoring antes de tiempo es hacer "boiler-plate", y por lo tanto una pérdida de tiempo. Hacer un refactoring tarde (o no hacerlo) que suframos un diseño feo y que apenas lo hagamos tengamos que arreglar todas las cosas que se hicieron mal porque el diseño anterior no lo permitía de otra manera. En cambio, hacer el refactoring justo antes de necesitar esa flexibilidad en el código por primera vez, es como cambiar el botellón cuando queda agua dentro del dispenser pero no en el botellón.
¿Y cómo nos damos cuenta cuándo estamos por necesitar una flexibilidad en el diseño? La verdad es que soluciones mágicas no conozco (si alguien sabe alguna, por favor que avise). Pero en mi experiencia programar test-first ayuda mucho.

Eso es todo, y espero que hayan disfrutado de las ilustraciones,
Aureliano.

2007-09-17

El cambio recién empieza




¿Siguen las cirujías? ¿Cómo va a terminar? ¿Como Moria Casán? ¿Cómo Zulema Yoma? ¿Como Michael Jackson?

2007-09-10

Un poquitín de Opera

Ayer a la noche fui a ver "Iphigénie en Tauride", de Gluck, interpretada por mi querida Compañía de las Luces. Como siempre (y aún más desde que dejé de cantar ahí) hicieron un espectáculo espectacular (redundantemente). Y están de suerte. Todavía quedan 2 funciones más, así que vayan.

Las dos funciones que quedan son el próximo sábado 15 y domingo 16 de septiembre a las 19:20hs en el Museo Nacional de Arte Decorativo. El mismo está en Libertador y Pereyra Lucena. Las entradas salen solamente $30.

2007-09-05

PHP GRASP

En mi laburo, Core Security, acaban de relesear un proyecto open source (licencia: Apache 2) que sirve para detectar SQL injections en PHP 5.2. El proyecto se llama GRASP y lo que hicieron mis compañeros de laburo es que se puede taintear cada caracter de un string y cuando se hace la llamada a la base de datos chequea las marcas en el string del query y controla si hubo un SQL injection o no.

En la versión actual chequea injections en mysql.

Me parece que se podría hacer algo para Rails. Así que si insisten lo suficiente (¡suscribanse a la lista y pidanlo!) en una de esas me dejan hacerlo. ¡Pidanlo ahora!

El site de GRASP es: http://grasp.coresecurity.com.

2007-08-31

Bug en rubygems 0.9.4

Hoy me crucé con un bug en la versión 0.9.4 de rubygems que hace que no tome de la línea de comando el proxy http, lo que hacía que no ande desde el laburo. Este bug está reportado y, por lo que dice en el bug tracker ya está arreglado en el repositorio de svn.

Pero si no quieren esperar a un nuevo release, se arregla muy fácil.

Busquen el archivo config_file.rb y pongan el siguiente código dentro de la clase ConfigFile (arriba de donde dice private):


def []=(key,value)
@hash[key.to_s] = value
end


Enjoy!
Aureliano.

2007-08-24

Pequeña alegría

Es bueno cuando el universo confirma algunas cosas, como que ruby es "1337".

Esto apareció hoy cuando miré mi gmail a la mañana:

2007-07-24

Una nación avanzada

Ayer a la noche caí que el partido de Lavagna tiene un acrónimo
recursivo. Siguiendo la tradición informática de "Joe's own editor",
"Sine is not emacs", "LAME Ain't an MP3 Encoder", "Wine Is Not an
Emulator" y "GNU's not UNIX", se viene "Una Nación Avanzada".

¿Lo habrán hecho apropósito?

¿Están buscando el voto nerd?

2007-07-07

Nitro

Como algunos de ustedes saben (y otros no), a mi me gusta Ruby como lenguaje de programación. Y, aparte, se me ocurrió (de nuevo) una idea para hacer una página web y llenarme de $$$$. Por supuesto que no les voy a contar la idea ;), porque no me gusta programar apurado.

Pero rails no me termina de gustar. Es medio fascista, como python. Tiene un montón de cosas que están buenas, como python, pero no me gusta que sea tan estructurado, como python. Tampoco me da hacerla en PHP (eso sí que es feo). Y como es algo que hago porque tengo ganas y con mis propios tiempos decidí probar algo nuevo. Así que me puse a revisar un framework web que viene creciendo hace rato, a la sombra de Rails.

El framework se llama nitro y en gems va por la versión 0.43 (o sea, tiene 43 releases, creo). Como hace 6 meses que no releasean nada, pero están laburando a full decidí agarrar la última versión del repositorio de desarrollo. Así que me instalé darcs e hice un "get" del repositorio. Después de un rato, encontrar un bug, reportarlo y que lo arreglen y con ayuda por IRC de uno de los tipos que lo desarrollan, hice andar el ejemplo que viene con nitro, un blog.

Por lo que estuve leyendo, el framework es más desestructurado que rails y te deja poner las cosas donde quieras y aparte el mapping relacional-objeto que tienen es copado (googleen "ruby og").

Les cuento que las gems de las que depende son: facets, xml-simple, RedCloth y uuidtools.

Bueno, por último les dejo algunos links:
* http://www.arnebrasseur.net/2007/07/01/the-daily-nitro/en/ (explica como "setupear" nitro para hacerlo funcar y de que gems depende, aunque les faltó incluir una dependencia, uuidtools)
* http://rubyforge.org/pipermail/nitro-general/2006-August/005832.html (en el medio del post explica cómo agarrar nitro del repositorio darcs en el que está la última versión "oficial").
* http://www.nitroproject.org/ (home page de nitro, todavía no está terminada).
* http://oxyliquit.de/ (site con tutoriales y preguntas y respuestas sobre nitro y og).
* http://blog.interlinked.org/tutorials/darcs.html (tutorial sobre como usar darcs).

Eso es todo amigos, me voy a hacer lo que todo geek que se precie hace un sábado a la noche, programar.

Aureliano.

2007-06-11

Charla de metaprogramación en Ruby

El viernes pasado di una charla de metaprogramación en Ruby en mi laburo. La misma duró algo así como una hora y media y me faltó mostrar algunas cosas (tenía que tardar una hora) y estuvo interesante (creo). Una hora y media a puro irb, sin slides y casi sin usar el pizarrón.

Acá pongo la planificación de la misma y algunos comentarios:

A continuación está la preparación de la charla:

Historia
Creado por Yukiro Matsumoto (AKA:Matz) en 1994 porque Perl no soportaba Kanji (encoding japonés). Se usó solo en Japón hasta que en el 2000 se publicó el libro: "Programming Ruby", primer libro de Ruby en inglés. Después lo agarró DHH e hizo Rails y se hizo famoso.

Comparaciones
Ruby tiene muchas de las cosas buenas de Perl, como soporte nativo con sintaxis propia para regex.
/\d+(\.\d+)?/ reconoce números (por ejemplo). Y como a Matz le gustaba Smalltalk, todo es un objeto.
También, como en Smalltalk, hay metaclases, las clases son objetos, todas las variables son referencias (no hay tipos primitivos) y se pueden pasar closures a los métodos.

Hands on
(las líneas que empiezan con >> las tipeo en el irb, las que empiezan con => son lo que escribe el irb solo, las que están en corchetes las pongo en un archivo)
En ruby podés hacer cuentas:

>> 1+1
=> 2

asignar a variables, usar strings:

>> var = "hola"
=> "hola"
>> var
=> "hola"

usar expresiones regulares para hacer cosas:

>> "5 mas 95 es 100".gsub( /\d+/, "numerito" )
=> "numerito mas numerito es numerito"

tambien hay una cosa que se llaman símbolos (que son como los símbolos de Lisp) y se escriben así:

>> :mi_simbolo

a muchos objectos (incluidos los simbolos) les puedo pedir que se muestren como strings:

>> :mi_simbolo.to_s
=> "mi_simbolo"

la diferencia entre los símbolos y los strings es que puede haber muchos strings con el
mismo texto pero solo un symbol con ese texto (object_id es un número único del objecto,
o sea que si dos objectos tienen el mismo número son el mismo objeto):

>> :mi_simbolo.object_id
=> 359538
>> :mi_simbolo.object_id
=> 359538

el object id es el mismo.

>> "mi_simbolo".object_id
=> 24163140
>> "mi_simbolo".object_id
=> 24160510

el object id es distinto.

También, como en Perl, hay interpolación de strings

>> "1 mas 1 es #{1+1}"
=> "1 mas 1 es 2"

Y como lo que devuelve es un string posta:

>> "1 mas 1 es #{1+1}".gsub( /\d+/, "numerito" )
=> "numerito mas numerito es numerito"

podés aplicarle todas las operaciones de string.

Arrays:

>> [1,2,3]
=> [1, 2, 3]

Hashes:

>> h = { :a => "aa", :b => "bb" }
=> {:b=>"bb", :a=>"aa"}
>> h[:a]
=> "aa"

Bueno ahora vamos a definir una clase. Edito en el gvim:

[
class A
def initialize( param )
puts "Inicializando A con #{param}"
@inst_var = param
end

def hace_algo( param )
"#{@inst_var} #{param}"
end
end
]

mostrar que no tengo que pasar self como en python
y uso la clase en el irb (después de cargarla):

>> a = A.new( "toto" )
Inicializando A con toto
=> #

esto guarda "toto" en la variable de instancia

>> a.hace_algo( "parametro" )
=> "toto parametro"

y acá lo muestra.

La herencia es herencia simple igual a otros lenguajes, así que no la muestro.

Otra cosa medianamente distintiva de Ruby es el uso de módulos como mixin:
Mostrar todos los métodos de instancia que tienen "algo" en su nombre:

>> A.instance_methods.select { |m| m.include? "algo" }
=> ["hace_algo"]

escribo en un archivo:

[
module M
def otro_algo( param )
"otro " + hace_algo( param )
end
end
]

lo cargo y después:

>> class A; include M; end
=> A

eso pone los métodos definidos en M en la clase A

>> A.instance_methods.select { |m| m.include? "algo" }
=> ["hace_algo", "otro_algo"]

Esto inclusive modifica a los métodos de las instancias vivas:

>> a.methods.select { |m| m.include? "algo" }
=> ["hace_algo", "otro_algo"]

Y los ejecuto para mostrar como llamar desde el módulo a la clase:

>> a.otro_algo( "aaaaaaaaaaa" )
=> "otro inicial aaaaaaaaaaa"

Como acaban de ver cuando hice el include, las clases de ruby son abiertas. Alguien se acuerda de VB? Algo que siempre me gustó es que en vez de escribir "self" o "this" usamos "me".

Abro un archivo y escribo:

[
class Object
def me
self
end
end
]

Lo cargo (load ....) y lo uso:

>> me
=> main
>> me.class
=> Object

También lo puedo usar dentro de otras clases:

>> class A; def klass; me.class; end; end
=> nil
>> a.klass
=> A

Otro feature interesante es el de los bloques de código (AKA: closures)
Ya vimos un ejemplo del uso cuando miramos los nombres de los métodos definidos en A y a.
Mirando un toque más en detalle:

>> [1,2,3,4,5].each { |n| puts "Numero #{n}" }
Numero 1
Numero 2
Numero 3
Numero 4
Numero 5
=> [1, 2, 3, 4, 5]

También puedo hacer mis propios métodos que reciban bloques de código, recordando que las clases son abiertas, modifico Integer para iterar. (Acá nos desviamos un toque de la planificación y mostramos también como usar parámetros del método definido dentro del closure. Dejo la planificación original):

>> class Integer; def veces( &block ); (1..self).each { |n| block[n] }; me; end; end
=> nil
>> 3.veces{ |n| puts n }
1
2
3
=> 3

Los métodos se pueden definir en clases y en objetos, por ejemplo:

>> b = [1,2,3,4,5,6]
=> [1, 2, 3, 4, 5, 6]
>> def b.sarasa(toto); "sarasa #{toto}";end
=> nil
>> b.sarasa
ArgumentError: wrong number of arguments (0 for 1)
from (irb):71:in `sarasa'
from (irb):71
from :0

(ups, me olvidé de pasarle el parámetro).

>> b.sarasa( "aaaaaaaaaaaa" )
=> "sarasa aaaaaaaaaaaa"

En ruby puedo definir properties "tipo Delphi" (o C#). Para esto, hay varios métodos
definidos en la clase Module. Acá muestro uno:

>> class A; attr_accessor :sarasa; end
=> nil
>> a.sarasa = "SARASASASA"
=> "SARASASASA"
>> a.sarasa
=> "SARASASASA"

Ahora bien, attr_accessor es un método del lenguaje (no una palabra reservada) así que voy
a implementarlo de nuevo.

[
class Module
def my_attr_accessor( symbol )
instance_var = "@#{symbol}"
define_method( symbol ) { instance_variable_get instance_var }
define_method( symbol.to_s + "=" ) { |value|
instance_variable_set instance_var, value }
end
end
]


Hago load y lo uso:

>> class A; my_attr_accessor :toto; end
=> #
>> a.toto = 5
=> 5
>> a.toto
=> 5

Salvo por cuestiones de performance my_attr_accessor (y que le falta funcionalidad) es equivalente
al original. Toda la funcionalidad se puede implementar, pero tardaría más y no tengo tiempo ni ganas.

También se pueden hacer métodos de clase que son solo para una clase específica, usando la metaclase.

>> class A; def self.klass_method; "klass_method";end;end
=> nil
>> class A; klass_method; end
=> "klass_method"
>> class B; klass_method; end
NameError: undefined local variable or method `klass_method' for B:Class
from (irb):75
from :0

Notar que lo que hice es definir un método para una sola instancia de la clase Class.

>> class C < A; klass_method; end
=> "klass_method"

También vale para las clases que heredan de la misma. Esto es lo que hacen en Rails para poder hacer:

class Entity < ActiveRecord::Base
has_many :other_entity
end

Como en Smalltalk, se puede hacer override de method_missing para hacer proxies dinámicos y esas cosas (en la charla tuve que saltear esta parte porque venía atrasado de tiempo, así que se perdieron mi DSL de diálogos de pelis porno):

[
class A
def method_missing( method_id, *args, &block )
action = "action_#{method_id}"
(respond_to? action) ? send(action) : super( method_id,*args, &block )
end

def action_a
puts "AAAAAAhhhh"
end

def action_o
puts "OOooohhhh"
end
end
]

Y lo uso:

>> load "bdlv.rb"
=> true
>> a.a
AAAAAAhhhh
=> nil
>> a.o
OOooohhhh
=> nil
>> a.metodo_que_no_existe
NoMethodError: undefined method `metodo_que_no_existe' for #
from ./bdlv.rb:17:in `method_missing'
from (irb):107
from :0


Por último, mostré markaby:

>> require 'markaby'
=> true
>> mab = Markaby::Builder.new
=> #<Markaby::Builder:0x2ef2160 @auto_validation=true, @assigns={}, @output_meta
_tag=true, @builder=<inspect/>, @indent=0, @streams=[["<inspect", "/", ">"]], @h
elpers=nil, @tagset=Markaby::XHTMLTransitional, @output_xml_instruction=true, @o
utput_helpers=true, @elements={}>

>> mab.html do
?> head { title "Core se la banca" }
>> body do
?> h1 "Productos de Core"
>> ul do
?> li "Sarasa $500000000"
>> li "Sarasa2 $100000000"
>> li "Consulting priceless"
>> end
>> end
>> end
=> "<html><head><meta content=\"text/html; charset=utf-8\" http-equiv=\"Content-
Type\"/><title>Core se la banca</title></head><body><h1>Productos de Core</h1><u
l><li>Sarasa $500000000</li><li>Sarasa2 $100000000\n</li><li>Consulti
ng priceless</li></ul></body></html>"

Notar que es código ruby! Por ejemplo, puedo iterar:

>> mab = Markaby::Builder.new
=> #<Markaby::Builder:0x2ecec9c @auto_validation=true, @assigns={}, @output_meta
_tag=true, @builder=<inspect/>, @indent=0, @streams=[["<inspect", "/", ">"]], @h
elpers=nil, @tagset=Markaby::XHTMLTransitional, @output_xml_instruction=true, @o
utput_helpers=true, @elements={}>
>> mab.html {
?> body {
?> ul {
?> [ "Sarasa $500000", "Sarasa2 $100000", "Consulting priceless" ].each do
?> |item| li item
>> end
>> }
>> }
>> }
=> "<html><body><ul><li>Sarasa $500000</li><li>Sarasa2 $100000</li><li>Co
nsulting priceless</li></ul></body></html>"


Por supuesto, este html es básico pero esto es CÓDIGO. Por ejemplo, haciendo un form:

>> mab.html { body { form( :target => "http://sarasa" ) { input( :type => :submit ) } } }
=> "<html><body><form target="http://sarasa"><input type="submit"/></form></body></html>"


También mostré como yapa el ejemplo del tutorial de rake.

Y me faltó el ejemplo de como manipular Excel, pero lo dejo acá:

require 'win32ole'
# -4100 is the value for the Excel constant xl3DColumn.
ChartTypeVal = -4100;

# Creates OLE object to Excel
excel = WIN32OLE.new("excel.application")

# Create and rotate the chart

excel['Visible'] = TRUE;
workbook = excel.Workbooks.Add();
excel.Range("a1")['Value'] = 3;
excel.Range("a2")['Value'] = 2;
excel.Range("a3")['Value'] = 1;
excel.Range("a1:a3").Select();
excelchart = workbook.Charts.Add();
excelchart['Type'] = ChartTypeVal;

30.step(180, 10) do |rot|
excelchart['Rotation'] = rot
end

excelchart2 = workbook.Charts.Add();
excelchart3 = workbook.Charts.Add();

charts = workbook.Charts
charts.each { |i| puts i }

excel.ActiveWorkbook.Close(0);
excel.Quit();

2007-04-17

Mirando el largo plazo

Encontré este comentario en slashdot que me pareció buenísimo, así que quería compartirlo. Lo que leerán a continuación es mi traducción del mismo.


Las características que nuestra sociedad capitalista premia (la excelencia en algunos campos da una gran riqueza y la competencia en ciertas habilidades en el trato interpersonal son más importantes que la competencia en cuestiones técnicas, etc.) son, aparentemente, lo que queremos como sociedad. Si la paga es mejor, la oferta debería incrementar. Sin embargo, las cosas que están correlacionadas con una mayor tasa de nacimientos son: religión (más => más hijos), región del país, etc. Características que están negativamente correlacionadas son educación (una mayor educación, especialmente para las mujeres, reduce la natalidad), ingreso, etc.

Aún más interesante es el nivel de diversidad genética. Los más despreciados por la gente que destaca los valores "familiares" (madre soltera con muchos hijos de diferentes padres) son los que generan más diversidad genética. Caballeros como K-Fed producen múltiple descendencia con múltiples mujeres, asegurando la diversidad genética de su prole.

Esto es interesante porque después de varias generaciones con decreciente religiosidad, creciente educación y gente sana viviendo más, parece que estas mismas fuerzas biológicas están achicando estas características. Hace unos años salió un divertido editorial sugiriendo que Roe vs. Wade destruyó el partido demócrata (N. de A.: de EEUU) no porque los abortos fueran impopulares sino por todo lo contrario. Debido a la alta correlación de la opinión política de la gente con la de sus padres, y la correlación entre ser demócrata con abortar (es 2 o 3 veces más probable tener un aborto si la mujer es demócrata que si es republicana), hacen que 18 años después de Roe vs. Wade haya una reducción en el pool genétcio de los demócratas.

También, las mayores tasas de natalidad de los fundamentalistas de todas las religiones está causando una lenta regresión de las reformas y cambios de la "post-iluminación" en las comunidades religiosas. Las "iglesias protestantes tradicionales" están perdiendo gente, los católicos se mantienen, pero el crecimiento es en Sudamérica y Africa (N. de A.: espero que no tenga razón) mientras que su presencia en Europa se achica y los católicos americanos son porcentualmente cada vez más latinos, en el judaísmo está creciendo su ala ortodoxa (desde el 8% hace 20 años hasta el 15% ahora) que se está tirando a la derecha y las tasas de crecimiento de los musulmanes están ganándoles a todo lo demás.

Basicamente, nuestra cultura secular ateísta encontró tal grado de autoindulgencia y libertad que puede llegar a achicarse a si misma. La izquierda norteamericana constantemente acusa a Bush pero los cambios culturales en EEUU muestran que la demografía, y no la demagogia, es lo que causa este empuej político reaccionario.

Es sumamente interesante, pero yo lo encuentro en más alto grado de ironía (N. de A.: yo también), que las alas "bíblicas" "anti-evolucionarias" de todas las religiones, que eran marginales hace una generación, de golpe están ganando, mientras que las seculares, culturalmente basadas en la ciencia y la razón, están en retirada. Y la razón es que la gente "anti-evolucionaria" está exparciendo su material genético y haciendo crías para hacer avanzar su agenda, y la gente pro-ciencia pro-evolución está acotando su material genético con familias de 0 a 2 hijos.

De hecho, más molesto es que los hombres que se manejan de las forma socialmente más irresponsable -- engaños permanentes, divorcio, etc., generalmente son padres de muchos más niños que aquellos que "juegan respetando las reglas". Así que si el material genético influencia el comportamiento, vamos a encontrar que cada generación es un poquito más adúltera.....

Si está tendencia continúa, que por supuesto no va a pasar, las cosas se vana ir para el otro lado, pero ironicamente en 4 o 5 generaciones, vamos a tener una población general no-blanca, muy religiosa que va a la iglesia/sinagoga/mesquita regularmente mientras tienen relaciones adúlteras durante la semana.

:) Pero seriamente, ¿piensan que la derecha religiosa es mala ahora? En 50 o 60 años, si siguen duplicando en su tasa de natalidad al EEUU secular... van a ser la mayoría.

Divertidas observaciones demográficas amateurs...
Alex



A mi me asusta que no veo ningún motivo para pensar que esto no pueda ser así. Como la gente que me conoce sabe, me preocupa mucho más el crecimiento demográfico de los religiosos que de los adúlteros. ¿Estamos por entrar en otra Edad Media? ¿Nos salvarán los adúlteros? ¿Cómo evitarían este futuro?

2007-03-12

Experiencias con GMail

Hace unas semanas que estoy usando GMail como mi mail de cabecera. Este es el balance que hago del mismo.

Cosas buenas:

  • Siempre anduvo y rápido
  • Tags (AKA: labels)
  • Las conversations (están buenísimas para dar contexto a los mails).
  • Me gusta usar el search para los mails (de hecho ya lo hacía de antes).
Cosas malas:
  • No puedo abrir tabs en el Firefox con los mails (clickear un mail con el botón del medio del mouse no sirve para nada).
  • No hay API para manejar GMail.
  • La versión no-ajaxificada está incompleta y no se pueden agregar filtros ni tags nuevos.
En particular, los últimos 2 puntos hicieron imposible hacer un programita para traer los mails que tengo en Yahoo y ponerles etiquetas para matchear con las carpetas en las que tengo los mails clasificados allá. De hecho, con la rubygem que usaría para acceder a GMail (gmailer) no me anduvo crear tags nuevos (al menos cuando la probé desde el irb). Y, la verdad, no veo como hacer screen scrapping de la versión con AJAX de GMail.

Ya sé que puedo importar los mails por POP3, pero cuando tenés como 5000 mails, es mejor mantener la clasificación de los mismos. Igualmente, probar el traspaso de mails de Yahoo a GMail (que quedó abortado) sirvió para que aprenda a mandar mails con attachments y acentos en ruby via SMTP.

2007-03-09

Auto retrato technicolor


Solo lápices de colores. Nada de edición por computadora.

Auto retrato

Resultado del curso de dibujo

El martes pasado terminé el curso de dibujo que hice en la Academia Da Vinci. Tuve la suerte de tener unos compañeros copados y muy talentosos y un muy buen profesor. Ahí aprendí que es una paleta, algunos efectos ópticos que se generan con los colores (por ejemplo, en una imagen parece que los colores cálidos, como el rojo, están más adelante que los colores fríos, como el azul). Como centrar un dibujo, y varios etcéteras, todos muy interesantes.

Pero lo más importante es que estoy empezando (muy de a poco) a ver algunas cosas de otra manera. Empecé a ver como se combinan los colores, que paleta usaría para pintar las cosas, cuando algo está sin equilibrio, etcétera. Igual este es el primer paso de una maratón, así que no esperen que me vuelva en un artista plástico en 5".

Por último les muestro el resultado práctico del curso:

2007-03-07

Compositor de colores

Para los insensibles del color, como yo, les comento de una página web que está re-buena. En http://www.colorsontheweb.com/ tiene una compositor de colores. Le das el color base y te arma las paletas (monocromático, complementario, tríadas, etc.).

¡Una masa!

Encontré esta página mirando esta entrada de blog: http://www.glanzani.com.ar/?p=132

Enjoy!
Aureliano.

2007-03-05

Business card

Aprovecho el blog para hacerles una consulta,
Estoy considerando hacerme a mano las tarjetas para repartir en eventos. Mi idea es hacerlas en rojo, azul y amarillo con lápices aquarelables. Me pareció que le darían una onda más "tierna" y que se destacarían del resto. Pero no sé si quedarían mal. Así que escucho sus opiniones.

Así que las opciones que se me ocurren son:
1) Es la mejor idea que haya escuchado, voy a hacerlo yo también.
2) Puede ser que esté bueno.
3) Me parece medio tonto.
4) Das una imagen poco profesional.
5) Yo no contrataría a alguien que hace sus tarjetas así ni por casualidad.
6) Va a parecer que torturás una familia de niños tailandeses para hacer hacer tus tarjetas (y eso sólo está bien para las zapatillas).

Los escucho atentamente,
Aureliano.

2007-03-04

Me pasé a GMail

Les cuento que mi nueva dirección de correo es aurelianocalvo at gmail.com. La dirección de Yahoo está forwardeada a la nueva, así que por el momento si me mandan mails a Yahoo los seguiré viendo (aunque con una pequeña demora).

El motivo del pase es que Yahoo! estuvo inestable como 3 días seguidos y no podía acceder a mi mail. Ahora me voy a tener que adaptar a usar labels en vez de folders (en ppio no parece malo).

Éxitos,
Aureliano.

2007-02-19

Jugando con greasemonkey

Estuve probando un plugin re-groso para Firefox que se llama greasemonkey. El mismo permite ejecutar JavaScript arbitrario después de que se cargue cada página.

Usandolo, hice un pequeño script para sacar la molesta propaganda que ponen en el nuevo Yahoo Mail Beta. El script tiene 10 líneas y lo puse acá. Pero para que no tengan que cliquear, se los posteo acá mismo.


// ==UserScript==
// @name Yahoo Beta Ads Blocker
// @namespace http://mywebsite.com/myscripts
// @description Yahoo Beta Ads Blocker
// @include *.mail.yahoo.com
// ==/UserScript==

function $(id) {
return document.getElementById(id);
}

function remove(id) {
var elem = $(id)
if (elem) {
elem.parentNode.removeChild(elem)
}
}

window.addEventListener(
'load',
function() {
remove('largePane')
remove('emptyFolderFrame')
remove('nwPane')
remove('swPane')
},
true
);


Enjoy!
Aureliano.

Si quieren ver más detalles sobre el greasemonkey vayan a http://greasemonkey.mozdev.org/

2007-02-16

Los lenguajes de la web

Para programar páginas web hay que aprender unas cuantas cosas. En particular es llamativa la cantidad de lenguajes que hay que aprender:

  1. HTML
  2. JavaScript
  3. CSS
  4. XML
  5. XPath
  6. CSS selectors
  7. Javascript
  8. Lenguaje y bibliotecas server side de tu preferencia (Ruby on Rails, PHP, Perl, Java, JSP, EJBs, ASP.NET, etc)
  9. SQL?
Sin embargo, la mayoría de estas cosas son carga cognitiva al dope. Es mi opinión que el desarrollo web se simplificaría bastante ordenando este quilombo.

En primer lugar, en vez de usar HTML, se podría usar una biblioteca en JavaScript para generarlo (algo como markaby pero hecho en JavaScript). Esto haría que sea más fácil generar dinamismo en el cliente.

Los CSSs deberían ser una biblioteca que encaja con la biblioteca anterior. Si quieren separar los datos para que los maneje un diseñador, podría perfectamente usarse JSON.

El XML es 100% reemplazable por JSON (que, es más lindo para escribir datos y todo). JSON (y javascript) es lo que usan varias bibliotecas de AJAX (ATLAS, prototype) para comunicar cambios en la página.

XPath puede llegar a ser algo práctico, pero solamente para navegar por árboles de objectos (no XML). Quizás una biblioteca para buscar cosas en JSON con sintáxis parecida estaría buena.

Los CSS selectors son una creación abominable. No aportan nada al XPATH, pero como están en los archivos de estilo, no queda otra que usarlos.

Con respecto al server, estoy esperando que alguien haga JavaScript on Rails (la capacidad de metaprogramación está ahí) y lo enchufe con algún intérprete de Javascript. "¿Harías Rails en el cliente?", se preguntarán. Nop. La idea es usar el mismo lenguaje en el cliente y en el server. Netscape lo intentó hace un tiempo pero se le acabo la plata. El mundo sería mejor si Sun hubiera apoyado esto en vez de impulsar Java a diestra y siniestra. Tener el mismo lenguaje en cliente y server permitiría hacer algunas cosas que ahora no se puede, como compartir el código de validación formato de los datos entre cliente y server sin repetir nada.

Y, por último, SQL es lo que intentamos sacarnos desde hace años de encima. Cada ORM (Hibernate, ActiveRecord) que hay es un intento fallido para escaparle.

¿Y por qué no lo ven así? Lo que hay que darse cuenta es que programar una página web dinámica es un ejercicio de metaprogramación. Un escribe un programa (que está en el server) que cuando se ejecuta genera un programa que se transmite al cliente (HTML + Javascript + CSS, etc) que cuando se ejecuta se renderea y muestra la página. Cuando se hace AJAX, en realidad hacés un hot fix en un sistema productivo. El resultado de una llamada AJAX son instrucciones de como cambiar el programa que está corriendo.

Pensado de esta manera, es razonable ver que conviene unir lenguajes en uno solo. JavaScript, a pesar de no ser mi lenguaje favorito (que es Ruby), para mi tiene todas las de ganar.

Tiene:
  • Soporte en el cliente.
  • Es conocido por los desarrolladores de páginas web.
  • Es razonablemente metaprogramable.
Para mi, el mayor problema es que para pasar cachos de código hay que escribir demasiado. Un bloque de código, pasado a una función, se ve así:
foo( c, function(a, b) { return a+b })


En cambio, el mismo código en Ruby es:
foo(c) { |a,b| a+b }


De todas maneras, JavaScript ya está por todos lados y es razonablemente bueno. Lo más importante es que tiene soporte en el cliente, que es la parte más dificil de cambiar en una página web. Si no me creen, traten de hacer páginas que anden solamente en FireFox y diganles a sus usuarios que se lo instalen.

Por último, quería agradecerle a frinfrunfranfrun haberse bancado chatear conmigo de este tema, lo que hizo que me caiga la ficha sobre que escribir.

Éxitos,
Aureliano.

2007-02-15

Si no puedes con ellos, úneteles

En una nota anterior, dije que había demasiados egresados de la Escuela da Vinci. Bueno, mañana empiezo un curso de dibujo allí mismo.

Espero poder contrarrestar mi falta de sensibilidad estética, y poder hacer programas (y/o páginas web) que no sean muy fe@s, sin ayuda de un diseñador. Sip, sólo no muy fe@s, hacer cosas lindas es realmente difícil y se los dejo a ellos.

Aureliano.

2007-02-14

Xara Extreme

Hoy estuve probando el editor vectorial de imágenes para Linux Xara (está en http://www.xaraxtreme.org/). Y me gustó. Está por la versión 0.7 y es un port de un programa de Windows. Aunque tiene algunos bugs, ya está usable y ¡estuve haciendo un dibujo!.

Les presento al "Señor Destapador":


¿Sugieren algún otro programa para reemplazar al Illustrator en Linux?

Aureliano.

PD: pueden usar esa imagen como quieran mientras me atribuyan la creación de la misma.

2007-02-13

Se termina kinesio

Si dios, la patria y los santos evangelios están conmigo; me quedan solamente 9 sesiones de kinesiología para la rodilla. Pero todavía no terminé :-(. Ahora me toca ir a un gimnasio a hacer pesas. Pesas y natación.

Tengo por lo menos 45 días de pesas. Aparentemente, todavía no tengo suficiente fuerza en el cuádriceps para que me den el alta. Se supone que puedo volver a las canchas (de paddle) en 2 meses, si no hay inconvenientes.

Éxitos,
Aureliano.

2007-02-05

Filtrado en el MSN

Están filtrando el envío de algunos URLs en MSN.

Acabo de confirmar que el URL http://www.scribemedia.org/2006/07/09/dhh/ ¡genera que la conexión del MSN se cierre! Parece que decidieron que Rails es competencia y lo empezaron a boicotear.

La verdad es que no me arrepiento en lo más mínimo de haber instalado KUbuntu en casa.

Saquen sus propias conclusiones,
Aureliano.

Update: en realidad parece que no dejan pasar mensajes que contengan el string ".scr" para evitar virus! ¡Qué patético!

2007-02-01

Maldito flash

Anteayer a la noche fuimos con Agustina a cenar a la casa de un amigo. Como nos tocó llevar el postre, hacía calor, Agus estuvo ocupada con un proyecto laboral, y yo tenía rehabilitación (de la rodilla, ¡malpensados!), decidimos comprar helado.
Entonces nos pusimos a buscar las heladerías en Google. Googleamos "sucursales Freddo" y nada. Googleamos "sucursales Persicco" y nada. Googleamos "sucursales Munchis" y nada.
¡Que raro! ¿Cómo puede ser?
¿No tendrán página web?
El problema es que hay demasiados egresados de la Escuela Da Vinci por ahí haciendo páginas web. Y hacen todo en Flash. Por lo tanto no podés linkear adentro de la página. Y aparte google no los indexa.

¡Basta de páginas web hechas en flash!

¡Quiero un google que ande!

¡Quiero mi helado!


Skip intro,
Aureliano.

2007-01-30

Carpetas _svn y radrails

La versión 1.0.3 de subclipse no se banca carpetas administrativas de svn con _svn. Pero la versión 1.0.4 sí. El problema es que RadRails (que es la customización de eclipse para programar sitios web con rails) viene con la versión 1.0.3.

Así que intenté hacer Help -> Update RadRails. Pero me dio un mensaje de error: RadRails (0.7.2) requires plug-in "org.eclipse.core.runtime (2.1.0)", or later version.

Buscando en la net no encontré ninguna solución fácil a este problema, así que me mandé a mirar como está armado RadRails y toqué un descriptor de eclipse para que no me de más ese error. Eclipse está compuesto por "features" que tienen "plugins". Y la configuración de RadRails exige en un feature que sea mejor o igual que otro, como indica el error.

Navegando un toque por los descriptores de las features encontré un candidato. En la línea 234 del archivo RadRails\feature\org.radrails.feature_0.7.2\feature.xml dice:

<import plugin="org.eclipse.core.runtime" version="2.1.0" match="greaterOrEqual">

Lo cambié a <import plugin="org.eclipse.core.runtime"> y Help -> Update RadRails empezó a funcar. Hice update, instalé subclipse 1.0.4 y listo el pollo.

Bueno, ahora tengo soporte para svn en RadRails 0.7.2 en Windows :D.

2007-01-21

Usos de la comida en el lunfardo para describir gente

Update: Gracias a Mariano, Diego, Anónimo y Florencia por sus aportes.

Estabamos charlando con mi mujer y encontramos que un montón de comida se usa en el lunfardo porteño para describir gente. He aquí algunas de ellas:

  • Banana: Piola, pero en forma despectiva. Uso: "Te pensás que sos re-banana por hacer esa boludez, ¿no?"
  • Papa frita: Tonto. Uso: "Sos un papa frita, ¿cómo vas a dejar el auto sin cerrar?".
  • Nabo: Tonto. Uso: "Flor de nabo resultaste vos, eh!"
  • Dulce: Tierno. Uso: "Mirá que dulce que es mi novio, me trajo flores"
  • Bombón: Linda. Uso: "Tu hermanita está hecha un bombón"
  • Maestra ciruela: Que explica cosas sin que le pidas. Uso: "Tu tía es una maestra ciruela"
  • Flan: Flojo. Uso: "Sos un flan".
  • Zanahoria: Tonto. Uso: "Flor de zanahoria resultaste"
  • Perejil: Gil. Uso: "Al final se la daba de re-banana y resultó un perejil"
  • Panqueque: que se da vuelta facilmente. Uso: "José se dio vuelta como un panqueque y nos cagó"
  • Ñoqui: que no labura pero va a cobrar. Uso: "Todos se quejan de los ñoquis pero quieren ser uno de ellos"
  • Salame: tonto. Uso: "Sos un salame"
  • Salamín: tonto (pero en forma cariñosa). Uso: "Salamín, el control remoto usa 2 pilas, no una".
  • Queso: que no juega bien al fútbol. Uso: "Aureliano es un queso"
  • Zapallo: Tonto. "Sos un zapallo"
  • Caramelito: Dulce, linda. "Tu hermana es un caramelito"
  • Radicheta: que pertenece a la Unión Cívica Radical. Uso: "Los radichetas ya no existen"
  • Pavo: Tonto. Uso: "Tu hermano es un pavo"
  • Vaca: gorda. Uso: "Susana es una vaca"
  • Pescado: tonto. Uso: "Sos un pescado"
  • Gallina: cagón. Uso: "Arrugaste, gallina". Hincha de River. Uso: "Los gallinas son todos gallinas".
  • Lechón: gordo. Uso: "Estás hecho un lechón"
  • Cerdo: gordo. Uso: "Estás hecho un gordo". Asqueroso. Uso: "Sos un cerdo"
  • Puerco: asqueroso. Uso: "Sos un puerco".
  • Torta: lesbiana. Uso: "Tu hermana es una torta"
  • Tortilla: lesbiana. Uso: "Tu hermana es una tortilla"
  • Vinagre: amargo/a, caraculico/a, malcogida. Uso: "La señorita Adriana es un vinagre"
  • Pancho: perezoso / tonto. Uso: "Dale, venite.. no seas pancho (perezoso) / Dale pancho, no ves que estás tirando todo al piso?!"
  • Chorizo: ladron. Uso: "Es un chorizo"
  • Limon: limado / quemado. Uso: "Dale limón! Rescatate!"
  • Manteca: flojo. Uso: "Eehh.. sos un mantequita al final vos, eh?"
  • Churro: pintón / fachero. Uso: "Es un churro bárbaro". porro. Uso: "Ese churro se fumó un churro y quedó de la cabeza"
  • Durazno: Duro / Que le cuesta razonar, aprender, etc. Uso: "Uff.. A este boludo le tengo que dedicar mas tiempo para enseñarle porque es medio durazno".
  • Bagre: Fea. Uso: "Esa mina es un bagre"
  • Papa: Jefe de la Iglesia Católica. Uso: "El Papa tiene cara de malo".
  • Batata: Que anda muy despacio. Uso: "Tu auto es una batata".
  • Tomate, del: loco. Uso: "Ahora sí quedo claro que Aureliano está del tomate".
  • Choclo: persona que tiene acne Uso, "que bagre mas feo es un choclo"
¿Se les ocurre algo más?