WordPress database error: [Table 'wp_ivr.wp_post2cat' doesn't exist]
SELECT post_id, category_id FROM wp_post2cat WHERE post_id IN (48,47,46,45,44)

Mi viaje en tren » 2007 » March

Archive for March, 2007

13 maneras de interpretar un símbolo de Ruby

WordPress database error: [Table 'wp_ivr.wp_post2cat' doesn't exist]
SELECT post_id, category_id FROM wp_post2cat WHERE post_id IN (48)

Uncategorized

Esta es una traducción de un artículo que leí hace mucho y que espero te sea útil. El artículo original fue escrito por Eric Kidd y se encuentra en blog “Random Hacks”:http://www.randomhacks.net/articles/2007/01/20/13-ways-of-looking-at-a-ruby-symbol.

Decidí traducir esto porque los símbolos son una de las cosas de Ruby que a mi me costo un poco de trabajo comprender, y si no tienes experiencia en esto, seguramente encontrarás algo útil aquí.

-

Programadores nuevos en Ruby con frecuencia preguntan, “¿Qué es, exactamente, un símbolo? ¿Y en que se diferencia de una cadena?” Ninguna respuesta funciona para todos, así que –con “disculpas a Wallace Stevens”:http://www.poets.org/viewmedia.php/prmMID/15746 – aquí hay 13 maneras de interpretar un símbolo en Ruby.

Un símbolo en Ruby es:

# …”el nombre de algo, no solo una masa de texto”:#1
# …”una etiqueta en una enumeración de forma libre”:#2
# …”una constante, un nombre único”:#3
# …”una cadena “internada””:#4
# …”un objeto de comparación O(1)”:#5
# …”un identificador de Lisp”:#6
# …”un identificador de Ruby”:#7
# …”la palabra clave para un argumento de palabra clave”:#8
# …”una excelente elección para una clave “hash””:#9
# …”como un OSType de Mac”:#10
# …”una fuga de memoria”:#11
# …”una forma astuta de almacenar una sola copia de una cadena”:#12
# …”un typedef de C llamado “ID””:#13

h3. 1. Un símbolo de Ruby es lo mismo que el nombre de algo, no solo una masa de texto

En Ruby, generalmente usamos símbolos cuando nos referimos a las cosas por su nombre:

[ruby]buscar_discurso(:gettysburg_address)[/ruby]

h6. (N. del T.: Gettysburg Address fue un discurso de Abraham Lincoln en 1863).

Pero para representar grandes trozos de texto, usaríamos cadenas:

[ruby]”Four score and seven years ago…”[/ruby]

h3. 2. Un símbolo de Ruby es una etiqueta en una enumeración de forma libre

En C++ (y muchos otros lenguajes), podemos usar “enumeraciones” para representar familias de constantes relacionadas:

[cpp]
enum EstadoBug { ABIERTO, CERRADO };
EstadoBug estado_original = ABIERTO;
EstadoBug estado_actual = CERRADO;
[/cpp]

Pero ya que Ruby es un lenguaje dinámico, no necesitamos preocuparnos por declarar un tipo *EstadoBug*, o estar al tanto de los valores legales. En lugar de eso, representamos los valores de la enumeración como símbolos:

[ruby]
estado_original = :abierto
estado_actual = :cerrado
[/ruby]

h3. 3. Un símbolo de Ruby es una constante, un nombre único

En Ruby, podemos cambiar el contenido de una cadena:

[ruby]”foo”[0] = ?b # “boo”[/ruby]

Pero no podemos cambiar el contenido de un símbolo:

[ruby]:foo[0] = ?b # Causa un error[/ruby]

Similarmente, podemos tener dos cadenas diferentes con el mismo contenido:

[ruby]
# El mismo contenido en la cadena, pero son diferentes objetos
“abierto”.object_id != “abierto”.object_id
[/ruby]

Sin embargo, dos símbolos con el mismo nombre son siempre el mismo objeto:

[ruby]
# Mismo nombre de símbolo, mismo objeto.
:abierto.object_id == :abierto.object_id
[/ruby]

h3. 4. Un símbolo de Ruby es una cadena “internada”

En Ruby, podemos convertir una cadena a un símbolo usando *intern*:

[ruby]”foo”.intern # devuelve :foo[/ruby]

*intern* mantiene una tabla de _hashes_ que mapea cadenas con su símbolo correspondiente. La primera vez que *intern* ve una cadena, crea un nuevo símbolo y lo almacena en la tabla. La siguiente vez que ve una cadena, *intern* devuelve el objeto original.

Podríamos implementar nuestra propia versión de *Symbol* e *intern* de la siguiente manera:
We could implement our own version of Symbol and intern as follows:

[ruby]
class MiSimbolo
TABLA={}
def initialize(str) @str = str end
def to_s() @str end
def ==(otro)
self.object_id == otro.object_id
end
end

class String
def mi_intern
tabla = MiSimbolo::TABLA
unless tabla.has_key?(self)
tabla[self] = MiSimbolo.new(self)
end
tabla[self]
end
end

“foo”.mi_intern
[/ruby]

h3. 5. Un símbolo de Ruby es un objeto con comparación O(1)

Para comparar dos cadenas, potencialmente tendremos que revisar cada caracter. Para dos cadenas de longitud N, esto tomara N+1 comparaciones (a lo que científicos en computación se refieren como “tiempo O(N)”).

[ruby]
def compara_cadenas str1, str2
return false if str1.length != str2.length
for i in 0…str1.length
return false if str1[i] != str2[i]
end
return true
end
compara_cadenas “foo”, “foo”
[/ruby]

Pero como cada aparición de *:foo* se refiere al mismo objeto, podemos comparar símbolos mirando sus IDs de objeto. Podemos hacer esto con una sola comparación (a lo que científicos en computación se refieren como “tiempo O(1)”).

[ruby]
def comparar_simbolos sym1, sym2
sym1.object_id == sym2.object_id
end
comparar_simbolos :foo, :foo
[/ruby]

h3. 6. Un símbolo de Ruby es un identificador Lisp

Los más antiguos ancestros de los símbolos de Ruby son los símbolos de Lisp. En Lisp, se usan símbolos para representar “identificadores” (nombres de variables y funciones) en un programa analizado. Digamos que tenemos un archivo llamado *doble.l* que contenga una sola función:

[code]
(defun doble (x)
(* x 2))
[/code]

Podemos analizar este archivo usando *read*:

[code]
(read “doble.l”)
;; Devuelve ‘(defun doble (x) (* x 2))
[/code]

Esto devuelve una lista anidada albergando los símbolos *defun*, *doble*, *, *x* (dos veces), y el número 2.

h3. 7. Un símbolo en Ruby es un identificador de Ruby

En Ruby, podemos buscar identificadores (nombres de variables, funciones, y constantes) mientras el programa se esta ejecutando. Esto típicamente se logra usando símbolos.

[ruby]
class Demo
# Lo que vamos a buscar por defecto.
DEFAULT = “Hola”
def initialize
@mensaje = DEFAULT
end
def habla() @mensaje end

# Usar símbolos para buscar identificadores.
def buscar_con_simbolos
[Demo.const_get(:DEFAULT),
method(:habla),
instance_variable_get(:@mensaje)]
end
end

Demo.new.buscar_con_simbolos
[/ruby]

h3. 8. Un símbolo en Ruby es una palabra clave para un argumento de palabra clave

Cuando pasamos argumentos de palabra clave a una función en Ruby, especificamos las palabras clave usando símbolos:

[ruby]
# Construir un URL para ‘bug’ usando Rails.
url_for :controller => ‘bug’,
:action => ’show’,
:id => bug.id
[/ruby]

h3. 9. Un símbolo en Ruby es una opción excelente para una clave de un _hash_

Comúnmente usamos símbolos para representar las claves en una tabla _hash_:

[ruby]
opciones = {}
opciones[:auto_guardar] = true
opciones[:mostrar_comentarios] = false
[/ruby]

h3. 10. Un símbolo en Ruby es como un OSType en Mac

El MacOS usa abreviaciones de cuatro caracteres para representar enumeraciones abiertas:

[code]
enum {
kTipoCarpetaSistema = ‘macs’,
kTipoCarpetaEscritorio = ‘desk’,
// …y así sucesivamente…
kTipoCarpetaPapelera = ‘trsh’
};
OSType carpeta = kTipoCarpetaSistema;
[/code]

En Ruby, usaríamos símbolos para el mismo propósito:

[ruby]
:carpeta_sistema
:carpeta_escritorio
:carpeta_papelera
[/ruby]

h3. 11. Un símbolo en Ruby es una fuga de memoria

Debido a la forma en la que los símbolos son almacenados en Ruby, “nunca pueden ser recolectados como basura”:http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/164890. Así que si creamos 10,000 símbolos de un solo uso que jamás volveremos a usar, nunca recuperaremos la memoria.

Algunas “implementaciones de Scheme”:http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/165011 usan una versión inteligente de *intern* que busca los símbolos usando una tabla de _hash_ débil. Esto permite que los símbolos sean recolectados sin destruir sus propiedades de unicidad.

h3. 12. Un símbolo en Ruby es una forma astuta de almacenar una sola copia de una cadena

(Para una idea similar, “ver este artículo”:http://glu.ttono.us/articles/2005/08/19/understanding-ruby-symbols)

Digamos que estamos trabajando en un analizador de lenguaje natural que intenta comprender ordenes de desayunos. Tenemos un cuerpo de 30,000 enunciados que representan ordenes reales, e intentamos encontrar patrones.

Pero incluso aunque tenemos un gran número de enunciados, el vocabulario en si es muy limitado. ¡No queremos almacenar 15,000 copias de la palabra “tocino” en memoria! En lugar de eso, podemos usar símbolos para representar cada palabra:

[ruby]
cuerpo = [
[:yo, :quiero, :un, :poco, :de, :tocino],
[:yo, :quiero, :unos, :huevos],
[:dame, :un, :poco, :de, :tocino],
[:tocino, :crujiente],
# … 29,995 frases más …
[:un, :poco, :de, :pan, :tostado, :por, :favor]
]
[/ruby]

En los primeros días de la IA, muchos programadores Lisp usaban exactamente esta estrategia para representar texto.

h3. 13. Un símbolo en Ruby es un typedef en C llamado “ID”

Internamente, Ruby 1.8 representa símbolos usando el ID del tipo. Esto es un *typedef* para un entero sin signo. Un ID representa una entrada en la tabla de símbolos de Ruby.

[cpp]
typedef unsigned long ID;
[/cpp]

Algunas funciones interesantes relacionadas con símbolos incluyen:

[cpp]
// Almacenar una cadena de C en una tabla de símbolos.
ID rb_intern(const char *nombre);
// Convertir un ID a un objeto Symbol.
#define ID2SYM(x)
// Convertir una cadena a un objeto Symbol.
VALUE rb_str_intern(VALUE s);
[/cpp]

h3. Otras explicaciones de símbolos de Ruby

Si ninguna de estas explicaciones te sirven, puedes probar suerte con alguna de las siguientes (en inglés):

# “Los símbolos no son cadenas inmutables”:http://onestepback.org/index.cgi/Tech/Ruby/SymbolsAreNotImmutableStrings.red
# “Usando símbolos por las razones incorrectas”:http://microjet.ath.cx/WebWiki/2005.12.27_UsingSymbolsForTheWrongReason.html
# “Otro blog más sobre símbolos en Ruby”:http://www.oreillynet.com/ruby/blog/2005/12/yet_another_blog_about_ruby_sy.html
# “Ahondando en símbolos de Ruby”:http://www.oreillynet.com/ruby/blog/2005/12/digging_into_ruby_symbols_1.html
# “Comprendiendo símbolos en Ruby”:http://glu.ttono.us/articles/2005/08/19/understanding-ruby-symbols

Aplicaciones Rails como aplicaciones de escritorio

WordPress database error: [Table 'wp_ivr.wp_post2cat' doesn't exist]
SELECT post_id, category_id FROM wp_post2cat WHERE post_id IN (47)

Uncategorized

Esto cada vez se pone más emocionante. “Slingshot”:http://joyeur.com/2007/03/22/joyent-slingshot es una plataforma que te permitirá que tus aplicaciones se ejecuten sin conexión a Internet, sincronizando los datos cuando sea necesario.

Además permitirá funciones que normalmente se atribuyen solo a aplicaciones de escritorio, como “arrastrar y soltar”.

En la página del anuncio hay más detalles, y en “Magnetk”:http://blog.magnetk.com/2007/03/22/joyent-slingshot/ hay más información sobre la tecnología.

También leanse los comentarios, hay varios interesantes.

La única desgracia es que no tienen planeado un cliente para Linux todavía, pero me parece que si van a tener una API, así que supongo que podría crearse.

Espero puedan cumplir con lo que se están proponiendo, ya que de ser así, entonces si una aplicación web va a poder competir de verdad con una de escritorio. De hecho la única razón por la que yo sigo usando aplicaciones de escritorio es porque no siempre tengo acceso a Internet, y esto lo cambiaría todo.

Ah, y va a funcionar sin que necesites modificar nada en tu aplicación.

¡Que año tan sabroso!

De vagabundos…

WordPress database error: [Table 'wp_ivr.wp_post2cat' doesn't exist]
SELECT post_id, category_id FROM wp_post2cat WHERE post_id IN (46)

Uncategorized

No, no me voy a salir del tema otra vez… Quiero comentar rápidamente sobre un plugin para Rails que le cambia los rieles normales a tu aplicación por los de un “maglev”:http://es.wikipedia.org/wiki/Maglev.

Se llama “Hobo”:http://hobocentral.net/. Lo que hace es facilitar muchas cosas (como si no fuera ya muy fácil), como un reemplazo para los RHTML (que la verdad esta bastante intrigante), mejora los scaffold, e incluye administración de usuarios, entre otras cosillas.

Si quieres ver como funciona puedes ver los “screencasts”:http://hobocentral.net/screencasts.php.

¿Computadoras para todos? ¡Por favor no!

WordPress database error: [Table 'wp_ivr.wp_post2cat' doesn't exist]
SELECT post_id, category_id FROM wp_post2cat WHERE post_id IN (45)

Uncategorized

Esto no tiene nada que ver con Ruby, pero es algo que desde hace tiempo quería compartir, así que perdonen que me salga del tema.

No se si sepan que desde hace algunos años existe un proyecto para fabricar computadoras portátiles que cuesten $100 USD. La meta se planea alcanzar para el 2008. Más información “aquí”:http://es.wikipedia.org/wiki/OLPC.

Mi opinión personal es que es una idea bastante tonta. ¿Para que rayos quiere un niño en una remota población africana una computadora?

No hablo de discriminación, pero pienso que el dinero que se invertirá en estas computadoras sería mucho, pero mucho mejor aprovechado si se usara para capacitar maestros, mejorar instalaciones escolares (o construirlas), desarrollar programas de estudio más efectivos, etc.

La computadora es como la TV. Nos quita mucho tiempo sin aportar mucho, en especial en países subdesarrollados.

En México también han habido iniciativas para equipar a escuelas públicas con computadoras. ¡Ya no hagan eso!

La computación es uno de esos temas que pronto se va a convertir en algo muy sencillo de comprender. Es como cuando el concepto del átomo era nuevo, ahora que ya tiene muchos años de antigüedad, es fácil para cualquier persona aprender sobre esto.

Un niño no necesita saber computación para desarrollarse. Esto lo puede aprender en el bachillerato o en la universidad, y especializarse en las áreas que sean afines a su carrera (AutoCAD para arquitectos, Photoshop para fotográfos, etc.).

La “Enciclomedia”:http://www.enciclomedia.edu.mx/ fue un gasto innecesario. Como mencione, ¿por qué no invertir en mejor capacitación, en viajes de campo, o incluso en enseñar herramientas mejores, como mapas mentales, buenas técnicas de lectura, etc.?

Ahora los niños ya casi no salen a jugar a la calle o a un parque. Recuerdo que cuando era niño todavía jugaba con el “bolillo”, jugaba “STOP”, y muchos otros. Ahora es más difícil ver que los niños de ahora hagan eso. Y ni que decir de lo que opinan nuestros padres y abuelos.

Ha habido casos en Corea por ejemplo, en el que chavos mueren por pasar demasiado tiempo frente a una computadora (esto no lo estoy inventando).

Una computadora nunca, pero nunca podrá reemplazar la enseñanza personal de un buen maestro. En la actualidad tal vez ese no sea el objetivo, pero apostaría a que poco a poco nos vamos a acercar a esa “meta”.

Así que ¿para que invertir en ese equipo que además va a ser obsoleto en poco tiempo? La buena educación perdura toda la vida… Mejor capaciten e informen a los ciber-cafés para que usen software libre, regalen a los alumnos tarjetas “tiempo aire” que puedan ser usadas en cualquier ciber, y asunto solucionado (bueno, no realmente, pero es mejor creo yo). Así además cada ciber se encarga de su propio mantenimiento.

La tecnología nos esta idiotizando. Veánse la película “Idiocracia”:http://www.amazon.com/dp/B000K7VHOG/ para darse un susto (y risa) de lo que puede pasar si seguimos así.

Estas últimas generaciones de niños vienen a levantar una revolución en el planeta y no les estamos haciendo la tarea muy fácil que digamos (ni a nosotros mismos)… aunque ninguna revolución es sencilla… ¡pero mejor flojitos y cooperando!

Me gustaría ahondar en algunas cosas, pero mejor lo dejo así… igual y en los comentarios se va desarrollando más.

PD: Por si queda la duda, no soy un retrógrada, solo estoy en contra del mal y excesivo uso de la tecnología… ahora denme chance de ir por mi traje de bombero antes de que me arrojen un molotov…

Houston, tenemos un problema

WordPress database error: [Table 'wp_ivr.wp_post2cat' doesn't exist]
SELECT post_id, category_id FROM wp_post2cat WHERE post_id IN (44)

Uncategorized

En “PC World”:http://www.pcworld.com/article/129517-1/ hay un artículo sobre un producto “nuevo” de Adobe (lo estaba desarrollando Macromedia), que sirve para crear aplicaciones web que puedan ser usadas sin conexión a Internet.

Si hicieran lo que Microsoft con .NET y permitieran que se pudiera usar cualquier lenguaje para programar (Ruby, por ejemplo :P), y además lo hicieran de código abierto, creo que aplastarían a Java y a .NET para este tipo de desarrollos. Se vale soñar…

Apollo va a ser liberado en pocos meses, así que solo cabe esperar a ver que pasa.

PD: Como ven, si, sigo vivo, ¡pero más ocupado que nunca!