Está en la página 1de 55

Todo lo que siempre quisiste saber sobre Ruby y no te vamos a contar

William Viana <wviana@aditel.org> Andreu Belmonte <andreu@aditel.org> 13 de noviembre

Contenidos

1 Introduccin 2 puts "Ruby mola mazo!" 2.1 2.2 2.3 Invocando el intrprete . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Tipos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.3.1 2.3.2 2.3.3 2.3.4 2.3.5 2.3.6 2.3.7 Nmeros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Cadenas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Smbolos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

4 5 6 6 7 7 8 9 9 10 12 13 14 15 15 16 17 1

Rangos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Expresiones regulares . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Hashes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

3 Condicionando y repitiendo 3.1 Expresiones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.1.1 3.1.2 3.2 if y unless . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . case . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Bucles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

William Viana y Andreu Belmonte 3.2.1 3.2.2 while y until . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . for . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

2 17 17 19 20 21 23 24 27 28 31 32 33 33 34 35 35 36 37 38 38 39

4 New kids on the block 4.1 Mtodos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.1.1 4.2 Cmo hacer bien un nger . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Bloques e iteradores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.2.1 Qu echan en el cine? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

5 Un lenguaje con clase 5.1 Clases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.1.1 5.1.2 5.2 5.3 Acceso . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Herencia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Mdulos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Mixins . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

6 Si no lo apunto se me olvida 6.1 6.2 6.3 La clase File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Bienvenido al mundo falible . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Qu voy a ver en el cine? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

7 Qt4-Ruby 7.1 7.2 Introduccin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Estructura de un interfaz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7.2.1 SignalnSlots: Connecting Peoples objects . . . . . . . . . . . . . . . . . . . . . . . . . .

William Viana y Andreu Belmonte 7.3 7.4 7.5 Diseo del interfaz: Designer-qt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Implementacin de la funcionalidad del interfaz . . . . . . . . . . . . . . . . . . . . . . . . . . . . Aplicacin principal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

3 40 44 45 46 47 47 50 51 52 53

8 Dice la leyenda que se empieza por documentar y se acaba por implementar 8.1 8.2 8.3 Introduccin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . SimpleMarkup o yo solo s HTML, como se juega a esto? . . . . . . . . . . . . . . . . . . . . . . y ahora?. . . ejecucin sobre nuestro cdigo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

9 Material relacionado 10 Agradecimientos 11 Sobre este documento

Introduccin

Ruby es un lenguaje de programacin orientado a objetos puro. Se basa sobretodo en la sintaxis de Perl y en la orientacin a objetos de SmallTalk. Fue creado por el japons Yukihiro Matz Matsumoto quien lo liber al pblico en 1995. Es distribuido bajo dos licencias: una propia y la GPL. Ruby es un lenguaje interpretado y no es de los ms rpidos. Matz lo que quera hacer era un lenguaje divertido de programar, en el que el programador pudiera ser muy productivo en poco tiempo. A m al menos divertido me resulta :) Sobre las versiones, la ltima versin estable es la 1.8.4 y la que est en desarrollo es la rama 1.9 que ser la futura versin 2.0 En este manual/tutorial aprenderemos lo bsico del lenguaje para empezar a programar scripts sencillos. Aprender a hablarlo uidamente ser cosa tuya. Talvez para la compresin de este manual haga falta ciertas nociones sobre programacin orientada a objetos, as que si no las tienes haz los deberes y al menos busca informacin en la wikipedia sobre el tema.

puts "Ruby mola mazo!"

2.1 2.2 2.3

Invocando el intrprete . Variables . . . . . . . . . . Tipos . . . . . . . . . . . . 2.3.1 Nmeros . . . . . . . . 2.3.2 Cadenas . . . . . . . . 2.3.3 Smbolos . . . . . . . 2.3.4 Rangos . . . . . . . . 2.3.5 Expresiones regulares 2.3.6 Arrays . . . . . . . . . 2.3.7 Hashes . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . .

6 6 7 7 8 9 9 10 12 13

William Viana y Andreu Belmonte

6 Todo lenguaje de programacin se empieza a aprender con un programa que imprime en pantalla "Hola mundo!". Nosotros seremos un poco ms originales, pero no demasiado, y aprenderemos a imprimir en pantalla "Ruby mola mazo!". De hecho eso es lo que justamente hace el ttulo del captulo. Sigamos con algo un poco ms serio.

2.1
Hay varias maneras de invocar el intrprete pasndole argumentos en la lnea de comandos. Por ejemplo con el parmetro -e podemos ejecutar cdigo desde la misma lnea de comandos: ruby -e puts "Hola mundo!" Con -c simplemente se comprueba la sintaxis del cdigo y con -w se activan los warnings. Para ver una lista con todas las opciones disponibles: man ruby

Invocando el intrprete

Los cheros de cdigo fuente de Ruby llevan la extensin .rb y el intrprete se llama ruby. Nuestro primer programa tendr este aspecto: hola_mundo.rb
#! / u s r / b i n / env r u b y p u t s " Ruby mola mazo ! " # e s t o e s un c o m e n t a r i o .

La primera lnea indica, en un sistema Unix, con qu intrprete se ha de interpretar ese chero. Para ejecutar nuestro programa desde la lnea de comandos podemos hacerlo as: ruby hola_mundo.rb o si el chero tiene permisos de ejecucin simplemente: ./hola_mundo.rb Tambin podemos usar el intrprete interactivo de Ruby que se llama irb.
i r b > p u t s " Ruby mola mazo ! " Ruby mola mazo ! => n i l

2.2
En realidad lo que se almacenan en las variables son referencias, no un valor. Esto puede causar algn dolor de cabeza si no se tiene en cuenta.

Variables

Las variables en Ruby no necesitan declararse y no tienen tipo, puedes almacenar en ellas lo que sea. Las constantes deben empezar con una letra mayscula y si intentas cambiar el valor de una constante durante la ejecucin Ruby te lanzar un warning. Las variables globales empiezan con un smbolo del dlar y las constantes globales con un dlar seguido de una letra mayscula. Algunos ejemplos de nombres de variables: foo bar Pi $IVA $Precio

William Viana y Andreu Belmonte Resta saber qu tipo de datos se pueden almacenar en una variable, sigue leyendo.

2.3
2.3.1

Tipos
Nmeros

Al principio he dicho que Ruby era un lenguaje orientado a objetos y ahora lo empezaremos a notar. Todos los tipos base en Ruby son objetos. Los nmeros enteros pertenecen a la clase Fixnum si estn comprendidos entre un rango 230 y 230 y Bignum para cualquier nmero entero fuera de ese rango. Tambin se pueden utilizar diferentes bases de representacin (binaria, octal, hexadecimal,...) Los nmeros reales pertenecen a la clase Float y tambin se pueden representar en notacin cientca.
i r b > 0xFF #h e x a d e c i m a l => 255 i r b > 0 b010 #b i n a r i o => 2 i r b > 020 #o c t a l => 16 irb> 0.000125 => 0 . 0 0 0 1 2 5 i r b > 1 . 2 5 e5 => 1 . 2 5 e 05 i r b > 1 . 2 5 e3 => 0 . 0 0 1 2 5 irb> 0.00125 => 0 . 0 0 1 2 5

El mtodo methods devuelve una lista con todos los mtodos disponibles del objeto. Otra manera de averiguar qu metodos tiene un objeto es ejecutar el interprete interactivo de ruby con la opcin de autocompletado irb readline -r irb/completion escribir un valor o variable seguido de un punto y darle al tabulador. Esto es vlido no slo para objetos de la clase Fixnum sino para cualquier objeto y es una buena manera de explorar los mtodos disponibles de una clase.

Como todo objeto de una clase los nmeros tienen sus propios mtodos.
irb> 42. c l a s s => Fixnum i r b > 3.abs #v a l o r a b s o l u t o => 3 i r b > 4 . succ #s u c e s o r de 4 => 5 i r b > 3 . 1 4 1 5 . to_i => 3

William Viana y Andreu Belmonte


i r b > 5 . times { p r i n t "JA" } JAJAJAJAJA=> 5

La ltima lnea quizs sea la nica que merece una explicacin. Traducido del ingls y ledo en voz alta pone esto: 5 veces imprime JA Muy legible, verdad? Casi se parece al lenguaje natural. Vayamos por partes: times es un iterador y lo que va entre llaves es el bloque que se le pasa al iterador. Dont panic! Veremos ms sobre iteradores y bloques ms adelante. 2.3.2 Cadenas

El primer carcter de una cadena es el de ndice 0. Adems se puede acceder a los caracteres de una cadena en orden inverso utilizando nmeros negativos: el ltimo carcter es el -1, el penltimo el -2,...

Una cadena es cualquier smbolo rodeado entre comillas dobles o simples.Las cadenas con comillas dobles permiten secuencias de escape, como \n o \t, y la potente expresin de evaluacin #{ }. Los operadores de suma y multiplicacin permiten concatenar y repetir cadenas. Ruby tiene adems el operador de adicin por el nal << para concatenar cadenas. Podemos letear una cadena con el operador de corte [x..y] donde x e y son nmeros enteros. El operador devuelve una subcadena formada por los caracteres entre las posiciones x e y de la cadena. Combinado con el operador de asignacin el operador de corte sirve para sustituir subcadenas de una cadena. Con unos ejemplos quedar todo ms claro:
i r b > p u t s " \tRuby mola #{mucho 3 } mas que Python " Ruby mola mucho mucho mucho mas que Python => n i l i r b > cad1 = " chunky " => " chunky " i r b > cad1 += " bacon " => " chunky bacon " i r b > cad1 << " " + cad1 => " chunky bacon chunky bacon " i r b > cad1 [ 7 . . 1 1 ] => " bacon " i r b > cad1 [ 0 . . 1 4 ] = " k e v i n " => " k e v i n " i r b > cad1

William Viana y Andreu Belmonte


=>" k e v i n bacon "

String, al igual que las otras clases de tipos base de Ruby, tiene muchos mtodos y no vamos a verlos todos aqu. Sus nombres son bastante autoexplicativos, recomiendo que los pruebes en el intrprete interactivo. Conocerlos har que amples vocabulario y alcances cierta uidez en el lenguaje.

Las cadenas pertenecen a la clase String y, cmo Ruby mola mucho, tienen un montn de mtodos molones que nos facilitan la vida. Y para muestra un botn: hola_fulanito.rb
1 2 3 4 5 p r i n t " I n t r o d u c e nombre y a p e l l i d o s : " nombre_completo = g e t s nombre_completo . s t r i p ! p r i n t " Hola " nombre_completo . each ( " " ) { | p a l a b r a | p r i n t p a l a b r a . c a p i t a l i z e , " " }

Para empezar vemos dos mtodos nuevos: print y gets. print es igual que puts pero no aade un salto de lnea al nal y gets lee una cadena del teclado. El mtodo strip! remueve el \n del nal de la cadena si lo hay. Los mtodos que terminan con un smbolo ! indican que el objeto va a ser modicado. Por ltimo, vuelve a aparecer un iterador y un bloque. Iteradores y bloques se usan mucho en Ruby y siempre los veremos cogidos de la mano. El iterador each sobre cadenas va tomando los valores de sus elementos. Por defecto considera que los elementos en una cadena estn separados por un \n, por eso le especicamos que tome como delimitador un espacio en blanco para que considere cada palabra como un elemento. Lo que va dentro de las barras verticales es la variable que interacta con el bloque; each le va pasando al bloque los valores que va tomando a travs de la variable palabra 2.3.3 Smbolos

Los smbolos empiezan por el smbolo : y pueden contener letras, dgitos o barras bajas. Para Ruby los smbolos son ms fciles de procesar que las cadenas. Generalmente los usars cuando necesites una cadena pero no necesites imprimirlo por pantalla, por ejemplo para pasarle un mensaje a un objeto. :soy_un_simbolo :rojo :mil :on :off 2.3.4 Rangos

Los rangos en Ruby tambin son un tipo. Se representan por dos valores entre parntesis separados por dos o tres puntos. (1..5) representa los nmeros del 1 al 5

William Viana y Andreu Belmonte (a..z) representa las letras de la a a la z (1...5) representa los nmeros del 1 al 4

10

El operador === sobre rangos sirve para comprobar si un valor est comprehendido en el rango, en caso armativo devuelve true y en caso contrario false. El rango ha de estar a la izquierda del operador: (1..10) === 5 2.3.5 En Ruby la ausencia de valor se expresa con la constante nil. Si no se le asigna un valor a una variable se le asigna por defecto nil Expresiones regulares

Sobre las expresiones regulares se han escrito libros enteros y dominarlas es casi ms difcil que aprender Ruby (talvez lo sea), pero son tremendamente tiles y los rubistas lo utilizan bastante, as que le dedicaremos algo de tiempo. En Ruby las expresiones regulares son un tipo base como las cadenas o los nmeros. Su utilidad es la de encontrar palabras o patrones en un texto o comprobar que algo cumple un patrn. Las expresiones regulares van delimitadas por barras. La manera ms simple de utilizar una expresin regular para buscar una palabra en una cadena sera la siguiente: texto.match(/Ruby/) El mtodo match compruebo si se cumplen las condiciones de la expresin regular, si se cumplen devuelve un objeto de tipo MatchData, en caso contrario devuelve nil. En nuestro ejemplo match comprueba si en la cadena est presente la palabra Ruby. El operador =, sirve para el mismo propsito que match pero devuelve la posicin del principio de la coincidencia en caso de que se cumpla y nil en caso contrario. Adems, en caso de coincidencia, asigna a las variables globales $,$& y $ la parte de la cadena anterior a la coincidencia, la parte de la cadena coincidente y la parte de la cadena posterior respectivamente.
i r b > " Programar en Ruby e s d i v e r t i d o " =~ /Ruby/ => 13 i r b > p u t s " #{\$}<<#{\$&}>>#{\$ } " Programar en <<Ruby>> e s d i v e r t i d o => n i l

Cuando lo que buscas en una cadena es una palabra es posible utilizar el operador [ ]. Nuestra bsqueda de la palabra Ruby en la cadena se podra haber hecho as: texto["Ruby"] Esto devuelve la cadena Ruby si sta est presente en la variable texto y nil en caso contrario.

Lo cierto es que siempre les he tenido mana a las expresiones regulares pero Ruby me ha hecho que me reconcilie con ellas. An as, an me cuesta utilizarlas

Las expresiones regulares disponen de algunos caracteres y combinaciones de caracteres con un signicado especial:

William Viana y Andreu Belmonte Smbolo [a-z] [ab] \d \w \s \b \D \W \S \B . {n} {n,m} {n,} * + ? () $ i Signicado Indica cualquier carcter entre la a y la z Indica o una a o una b Un dgito. Equivale a [0-9] Una letra, un dgito o una barra baja. Equivale a [A-Za-z0-9] Espacio en blanco [\t\r\n] Lmite de palabra cualquier cosa escepto dgitos. Equivale a [\d] es la negacin de \w es la negacin de \s es la negacin de \b cualquier carcter Exactamente n veces lo que precede Al menos n y como mximo m de lo que precede n o ms de lo que precede Cero o ms repeticiones de lo que precede Una o ms repeticiones de lo que precede Cero o una repeticin de lo que precede Agrupamiento La lnea empieza por lo que va a continuacin La lnea termina por lo que precede Puesto despus de la ltima barra delimitadora hace que no se distinga maysculas de minsculas

11

Algunas expresiones regulares:


/<\/?[^>]+>/ i /\d{8}[ \ s ] ? [ az ] / i /\d+:\d+/ / . + ( \ . png ) $ / i /\/\.\\// $ #una e t i q u e t a de a p e r t u r a o c i e r r e en l e n g u a j e h t m l #un DNI #una hora con f o r m a t o 0 0 : 0 0 #e l nombre de un a r c h i v o que t e r m i n a en png #un c o m e n t a r i o en l e n g u a j e C

William Viana y Andreu Belmonte 2.3.6 Arrays

12

Los arrays son colecciones de valores agrupados alrededor de corchetes y separados por comas. Un array puede contener valores de cualquier tipo y no necesariamente todos del mismo tipo. Como en la mayora de lenguajes de programacin, se puede acceder a un elemento usando un ndice dentro del operador [ ]. Los mtodos de repeticin, concatenacin y corte de las cadenas tambin sirven para los arrays. La diferencia importante con otros lenguajes de programacin es que si intentas acceder a un elemento que no est en el array no se produce un error de ndice fuera del rango sino que el array te devuelve el valor nil (ausencia de valor).
i r b > c a j o n = [ " c d s " , " l i b r e t a " , " b o l i g r a f o " , " l i b r o " , " c h i c l e pegado " ] => [ " c d s " , " l i b r e t a " , " b o l i g r a f o " , " l i b r o " , " c h i c l e pegado " ] irb> cajon [ 4 ] => " c h i c l e pegado " irb> cajon [ 2 . . 4 ] => [ " b o l i g r a f o " , " l i b r o " , " c h i c l e pegado " ] irb> cajon [ 6 ] => n i l irb> cajon [ 6 ] = " g a l l e t a " => " g a l l e t a " irb> cajon => [ " c d s " , " l i b r e t a " , " b o l i g r a f o " , " l i b r o " , " c h i c l e pegado " , n i l , " g a l l e t a " ] i r b > h a b i t a c i o n = %w/ e s c r i t o r i o o r d e n a d o r a r m a r i o e s t a n t e r i a / => [ " e s c r i t o r i o " , " o r d e n a d o r " , " a r m a r i o " , " e s t a n t e r i a " ]

El elemento de ndice 8 no tena ningn valor asignado, pero luego decido asignarle el valor galleta. Del ndice 6 no he dicho nada pero Ruby ha puesto ah un nil, en realidad es como si siempre hubieran estado ah pero antes no lo veamos. La ltima lnea es otra forma de inicializar un array de cadenas sin tener que estar escribiendo las comillas y las comas, muy cmodo. hola_fulanito2.rb
1 2 3 4 5 6 p r i n t " I n t r o d u c e nombre y a p e l l i d o s : " nombre_completo = g e t s . s t r i p nombres = nombre_completo . s p l i t nombres . each { | nombre | nombre . c a p i t a l i z e ! } nombre_completo = nombres . j o i n ( " " ) p u t s " Hola #{nombre_completo } ! "

William Viana y Andreu Belmonte

13

$ ruby h o l a _ f u l a n i t o 2 . rb I n t r o d u c e nombre y a p e l l i d o s : s e n y o r sombrero Hola Senyor Sombrero ! $

Ya s que es un ejemplo muy estpido pero slo quera que vieras como convertir cadenas en arrays, arrays en cadenas y que los arrays tambin tienen el iterador each. 2.3.7 Hashes

Tambin llamados vectores asociativos o diccionarios, los hashes (los rubistas preeren ese trmino) son como los arrays pero no estn ordenados y se accede a los elementos mediante una clave. Por tanto los hashes son una coleccin de pares clave, valor rodeados por llaves dnde clave y valor estn separados por los smbolos => y pueden ser de cualquier tipo. Por supuesto no pueden haber claves repetidas. Si se intenta acceder a una clave inexistente devuelve nil.
1 i n f o = { " nombre "=>" B r a u l i o da S i l v a " , 2 " p r o f e s i o n "=>" F o t o g r a f o de p l a t o s combinados " , 3 " a s p i r a c i o n "=>" Exponer en e l bar R e i n o l d s " 4 } 5 6 i n f o . each { | c l a v e , v a l o r | p u t s "#{c l a v e . c a p i t a l i z e } : #{v a l o r } " }

Un ejemplo estpido ms. A estas alturas creo que ya no merece ninguna explicacin. Ya hemos visto un poco ms o menos todos los tipos base de Ruby pero con eso slo no podemos hacer mucho. Subamos un peldao ms.

Condicionando y repitiendo

3.1

Expresiones . . . 3.1.1 if y unless . . 3.1.2 case . . . . . 3.2 Bucles . . . . . . 3.2.1 while y until 3.2.2 for . . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . .

15 15 16 17 17 17

14

William Viana y Andreu Belmonte

15 Bueno, me he dado cuenta de que quizs estoy tratando de explicarlo todo como si no supieras programar. Si no sabes programar te has equivocado de lugar. A partir de ahora vamos a ir un poco ms rpido (o no me dar tiempo de terminar el documento). Este captulo va de bucles y sentencias de control. En Ruby las sentencias de control son un poco diferentes de los dems lenguajes y en seguida veremos por qu.

3.1
3.1.1

Expresiones
if y unless

Puedes llamarle a if como te d la gana, me interesa que te acuerdes que devuelve un valor

En Ruby todo lo susceptible de devolver un valor lo hace. Por eso if, que en otros lenguajes decimos que es una sentencia de control, en Ruby diremos que es una expresin ya que devuelve un valor. Y qu valor devuelve? Pues el valor de la ltima lnea que se ha evaluado
1 2 3 4 5 6 7 8 d e j a r _ p a s a r = i f l i s t a . i n c l u d e ? B r a u l i o then : s i e l s e : no end i f d e j a r _ p a s a r == : s i p u t s " Pase por a q u i . " e l s i f Braulio . ofrece_soborno ? p u t s " Pase por a q u i c a b a l l e r o , y que t e n g a una a g r a d a b l e v e l a d a " else p u t s "No e s t a s en l a l i s t a , no e n t r a s . " end

Creo que queda bastante claro la sintaxis del if, pero lo dir de palabra. Si lo quieres hacer todo en la misma lnea tan horrible como he hecho yo en la lnea 1, has de incluir la palabra then despus de la condicin. Puedes anidar condiciones con elsif y aadir al nal un else opcionalmente. Al nal has de incluir la palabra end para nalizar el bloque. La identacin es opcional. La primera lnea del ejemplo anterior es realmente horrible, no recomiendo que hagas nunca algo as. Ruby tiene algo que puede hacer de esa lnea mucho ms elegante: los modicadores if. Esa misma lnea se podra haber escrito as dejar_pasar = :si if lista.include? Braulio

Esa asignacin se har slo si el pobre Braulio est en la dichosa lista. Si dejar_pasar no estaba inicializada y Braulio no estaba en la lista entonces, como toda variable no inicializada, se le asignar nil.

William Viana y Andreu Belmonte La expresin unless es la forma negada de if. if foo != 0 equivale a unless foo == 0 Por ltimo hay que recalcar una diferencia importante entre Ruby y otros lenguajes: sorpresa.rb
1 2 3 4 5 6 foo = 0 i f foo p u t s " Seguro que no t e e s p e r a b a s que s e i m p r i m i e r a e s t o " else p u t s "Y e s p e r a b a s que s e i m p r i m i e r a e s t o o t r o " end

16

unless me parece un poco raro pero no s por qu lo uso bastante, supongo que por la novedad. Est genial eso de escribir un manual, uno puede poner lo que le d la gana con total libertad. Os lo recomiendo.

El nico caso en el que se ejecutara el bloque de cdigo del else sera cuando foo fuera igual a nil o a false. 3.1.2 case

case es como el switch de C. Para quien no conoce el switch de C, es parecido a tener varios elsif anidados, pero con una sintaxis ms cmoda. precio_musica.rb
1 o p i n i o n _ p e r s o n a l = case precio_de_un_cd 2 when 0 . . . 5 3 " genial " 4 when 5 . . . 1 0 5 " razonable " 6 when 1 0 . . . 1 5 7 " e s p e r o que t e n g a un l i b r i t o c h u l o " 8 when 1 5 . . 2 0 9 " un poco caro , p e r o s i l l e v a dvd e s a c e p t a b l e " 10 else 11 " un abuso " 12 end

Se evala lo que va justo despus del case y se compara usando el operador ===. Al igual que con el if si quieres hacerlo todo en la misma lnea has de incluir la palabra then, sino puedes omitirla.

William Viana y Andreu Belmonte

17

3.2
3.2.1

Bucles
while y until

El bucle while se ejecuta mientras se cumpla una condicin y until mientras no se cumpla. Al igual que if y unless, while y until se pueden usar como modicadores. newpass.rb
1 opcion = 0 2 u n t i l o p c i o n == 2 3 p u t s " 1 I n t r o d u c i r nuevo password " 4 puts " 2 S a l i r " 5 opcion = 0 6 u n t i l ( 1 . . 2 ) === o p c i o n 7 print " Introduce opcion : " 8 o p c i o n = STDIN . g e t s . to_i 9 end 10 i f o p c i o n == 1 11 p r i n t " I n t r o d u c e nuevo password : " 12 password = STDIN . g e t s . r s t r i p 13 u n t i l password . match ( / ^ . { 8 , 1 5 } $ / ) 14 p u t s " El password ha de t e n e r de 8 a 15 c a r a c t e r e s " 15 p r i n t " I n t r o d u c e nuevo password : " 16 password = STDIN . g e t s . r s t r i p 17 end 18 p u t s " Password a c t u a l i z a d o " 19 end 20 end

Bien, los ejemplos poco a poco los puedo hacer ms interesantes. Si has llegado hasta aqu creo que ya eres capaz de entender ese trozo de cdigo sin que tenga que explicar nada (creo que incluso alguien que no hable Ruby puede entenderlo). 3.2.2 for

El bucle for itera sobre colecciones al igual que hace el iterador each. Tiene una sintaxis muy parecida a Python:

William Viana y Andreu Belmonte

18

1 f o r e l e m e n t o in i t e r a b l e 2 ... 3 end

iterable es cualquier cosa sobre la que se pueda iterar (un rango, un array, una cadena, un diccionario), de hecho Ruby traduce eso a algo como:
1 i t e r a b l e . each { | e l e m e n t o | ... }

New kids on the block

4.1

Mtodos . . . . . . . . . . . . 4.1.1 Cmo hacer bien un nger 4.2 Bloques e iteradores . . . . . 4.2.1 Qu echan en el cine? . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . .

. . . .

. . . .

. 20 . . 21 . 23 . . 24

19

William Viana y Andreu Belmonte El ttulo de ese captulo es una referencia al grupo del mismo nombre de los 80. Cuando era pequeo mi hermana mayor me torturaba con su msica

20 Estaba deseando que llegara este momento. Es el momento de presentar (in)formalmente una de las cosas que ms me gusta de Ruby: iteradores y bloques. En este captulo tambin veremos como denir mtodos. Empecemos por lo ms fcil.

4.1

Mtodos

Denir tus propios mtodos es bien fcil, veamos su sintaxis y alguna peculiaridad: metodos.rb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 def cuadrado ( x ) return xx end def t r i a n g u l o s " son a d i f e r e n t e s de l o s c u a d r a d o s " #s e puede o m i t i r l a p a l a b r a r e t u r n end def metodo ( uno , dos , v a r i o s ) "Me han pasado #{uno } , #{dos } , #{ v a r i o s . j o i n ( , end def es_palindromo ? ( f r a s e ) f r a s e = f r a s e . dup #hago una c o p i a de f r a s e f r a s e . gsub ! ( " " , " " ) . downcase ! == f r a s e . r e v e r s e end p u t s " Cuadrado de 2 = #{cuadrado 2} " p u t s " Los t r i a n g u l o s son " + t r i a n g u l o s p u t s metodo ( " c o c a i n a " , " h a c h i s " , " mariguana " , " e x t a s i s " ) p u t s metodo ( ( 1 . . 3 ) . to_a) f r a s e = " Dabale a r r o z a l a z o r r a e l abad " i f es_palindromo ? f r a s e p u t s " \"#{ f r a s e } \ " e s un palindromo " else p u t s " \"#{ f r a s e } \ " no e s un palindromo " end

) }"

William Viana y Andreu Belmonte

21

$ ruby metodos . rb Cuadrado de 2 = 4 Los t r i a n g u l o s son a d i f e r e n t e s de l o s c u a d r a d o s Me han pasado c o c a i n a , h a c h i s , mariguana , e x t a s i s Me han pasado 1 , 2 , 3 " Dabale a r r o z a l a z o r r a e l abad " e s un palindromo $

A partir de la versin 1.9 de Ruby en esos casos ser obligatorio incluir los parntesis para la llamada del mtodo

Lo primero que llama la atencin es que se puede omitir la palabra return ya que por defecto los mtodos devuelven el valor de la ltima lnea evaluada. Con *varios en la lnea 10 lo que se consigue es que el mtodo pueda recibir un nmero variable de parmetros, varios es convertido en un array con esos parmetros. Otra cosa que se puede omitir son los parntesis en la llamada al mtodo, lo hemos estado haciendo todo el rato con puts y print, pero en llamadas del tipo: puts cuadrado 4 puede resultar confuso la omisin de los parntesis, entonces se recomienda incluirlos. . Si un mtodo no recibe argumentos no es necesario incluir los parntesis ni en la denicin ni en la llamada al mtodo. 4.1.1 Cmo hacer bien un nger

Tranquilidad, esto no tiene nada que ver con el sexo (aunque por supuesto el ttulo est puesto a conciencia), slo voy a proponer un ejercicio. Sigue leyendo. El comando nger en los entornos Unix nos da informacin sobre un usuario si le proporcionas un nombre de usuario. Como ejercicio para practicar un poco te propongo que hagas un nger que pueda recibir tanto un nombre de usuario como el nombre real de la persona (completo o no) y que muestre por pantalla su nombre y su nombre de usuario en el sistema. Has de tener en cuenta que si se proporciona un nombre muy comn pueden haber varios usuarios con el mismo nombre, por ejemplo podras mostrar todas las coincidencias. Para hacerlo vas a necesitar abrir el chero /etc/passwd, pero an no he explicado como abrir cheros. Bueno, aqu va una manera que creo que entenders fcilmente:
1 F i l e : : open ( " / e t c / passwd " ) . each { | l i n e a |#p r o c e s a r }

Para los parmetros pasados por la lnea de comandos puedes utilizar ARGV, que es una lista con todos los parmetros pasados en la lnea de comandos, teniendo en cuenta que el primer elemento es el primer argumento

William Viana y Andreu Belmonte

22 y no el nombre del programa, como en otros lenguajes como C. No te preocupes mucho por el tratamiento de errores. De todas formas dejo un ejemplo hecho pero recomiendo que lo intentes hacer por tu cuenta sin mirarlo y luego comparar (puede que lo hayas hecho mucho ms elegante y te podrs rer de m). nger.rb
1 #! / u s r / b i n / env r u b y 2 def b u s c a r ( i d ) 3 lista = [] 4 F i l e : : open ( " / e t c / passwd " ) . each do | l i n e a | 5 l i s t a << l i n e a i f l i n e a . match ( /#{i d } / i ) 6 end 7 l i s t a . c o l l e c t ! do | d a t o s | 8 datos = datos . s p l i t ( " : " ) 9 v a l o r = d a t o s [ 0 ] , d a t o s [ 4 ] # me quedo con l o que me i n t e r e s a 10 end 11 12 i f l i s t a . l e n g t h > 1 #m u l t i p l e s matchs 13 l i s t a . each_with_index do | v a l o r , i n d i c e | 14 p u t s " [#{ i n d i c e } ] #{v a l o r [ 1 ] } " 15 end 16 p r i n t " E l i j e uno : " 17 u n t i l ( 0 . . . l i s t a . l e n g t h )===(i n d i c e = STDIN . g e t s . to_i ) 18 p r i n t " E l i j e uno : " 19 end 20 l i s t a [ indice ] 21 else 22 lista [0] 23 end 24 end 25 26 i f ARGV. l e n g t h == 1 27 l o g i n , nombre = b u s c a r (ARGV[ 0 ] ) 28 i f l o g i n or nombre 29 p u t s " Login : #{ l o g i n } " 30 p u t s " Nombre : #{nombre} " 31 else 32 p u t s "No he e n c o n t r a d o e s e u s u a r i o "

Si tienes curiosidad, en Ruby el nombre del programa se almacena en la variable global $0

William Viana y Andreu Belmonte


33 34 e l s e 35 36 end end p u t s " Numero e r r o n e o de argumentos "

23

4.2

Bloques e iteradores

Un bloque es un trozo de cdigo encerrado entre {} o entre las palabras clave do y end:
{ p u t s "Un b l o q u e s i m p l e " } do p u t s "Un b l o q u e " p u t s " con v a r i a s l i n e a s " end

Generalmente cuando el bloque tiene ms de una lnea se usa la sintaxis do..end. La gracia de los bloques es que se les puede pasar como un argumento a un mtodo. bloques.rb
1 2 3 4 5 6 def metodo ( f o o ) yield f o o yield f o o 2 end valores = [ ] metodo ( 3 ) { | x | v a l o r e s << x} # a l t e r m i n a r v a l o r e s = [ 3 , 6 ]

Parece algo confuso, no? Yo la primera vez que vi algo as me lo pareci. Le estamos pasando a metodo la constante 3 y un bloque de cdigo. A algunos les gusta pensar que yield lo que hace es pegar el bloque de cdigo ah donde es llamado pero en realidad lo que hace es devolverle el control al bloque, ste se ejecuta y devuelve el control al mtodo. Bloques y mtodos tienen un mbito distinto, lo que es local al mtodo no es accesible por el bloque pero yield puede interactuar con el bloque pasndole variables. Las variables que va a recibir el bloque van encerradas entre | | y separadas por comas. En nuestro ejemplo metodo recibe el valor 3 y lo primero que hace es pasarle el control al mtodo envindole el valor de la variable foo (que es 3), el bloque la recibe y la mete en el array valores, a continuacin el bloque

William Viana y Andreu Belmonte

24 devuelve el control al mtodo y justo al volver se encuentra con otro yield que vuelve a devolver el control al bloque (como en un juego de ping-pong) pero esta vez le pasa el valor de foo multiplicado por 2. Al nal en valores habr un 3 y un 6. Ahora te puedes hacer una idea de como est implementado un mtodo each. Un each de nuestra propia clase Array podra ser algo como esto: mi_each.rb
1 def each 2 i = 0 3 while i 4 5 6 end 7 return 8 end

< self . length yield s e l f [ i ] i+=1 self

Y eso era un iterador. Vale, an no he explicado nada de clases, tendr que dar un adelanto. self es como el puntero this del lenguaje C++, es una referencia al propio objeto que llama al mtodo. 4.2.1 Qu echan en el cine?

Veamos un ejemplo que luego resultar til. Vamos a la web del cine que suelo frecuentar ultimamente, en concreto a la seccin cartelera: . Vamos a parsearla y quedarnos slo con los ttulos de las pelis. Para ello tenemos que echar una ojeada al cdigo de la pgina y buscar patrones. Miro el cdigo, basura, basura, basura, lo tengo!
<s e l e c t name=" p e l i c u l a I D " i d=" p e l i c u l a I D " onchange=" m u e s t r a P e l i c u l a ( ) ; "> <o p t i o n v a l u e=" 0 ">p e l i c u l a s </o p t i o n > <o p t i o n v a l u e=" 34 ">C o l e g a s en e l Bosque</o p t i o n > <o p t i o n v a l u e=" 40 ">El C o r r a l , Una F i e s t a Muy B e s t i a </o p t i o n > .... </s e l e c t >

Los ttulos de las pelis estn en una zona que empieza con <select name="peliculaID"... > y termina con un </select>. Cada ttulo va entre las etiquetas <option ...> ttulo de la peli</option>. Ya tenemos los patrones, y ahora qu? Lo primero ser poder bajarse el cdigo de esa pgina para poder tratarlo. Gracias a un japons,

William Viana y Andreu Belmonte

25 que del nombre no me acuerdo, est disponible en Ruby 1.8 la biblioteca open-uri que nos permite abrir un chero via http y tratarlo como si fuera un chero de texto normal:
1 r e q u i r e openu r i 2 web = open ( " h t t p : / /www. n e o c i n e . e s / i n d e x . php ? s=c a r t e l e r a&i d=7" ) 3 web . e a c h _ l i n e { | l i n e a | p u t s l i n e a }

require carga el cdigo de otro chero

La estrategia ser la siguiente Leer el chero lnea a lnea hasta encontrar una lnea que contenga <select name="peliculaID ...> A partir de entonces leer cada lnea y extraer el ttulo de la peli eliminando las etiquetas feas... ...hasta que encuentres una etiqueta de cierre </select> Vale, ahora es cuando las expresiones regulares nos vienen bien. Intenta escribir t una expresin regular que empiece por <select name="peliculaID seguido de cualquier cosa que no sea un > y luego un smbolo >. Si te rindes mira la solucin: /<select name="peliculaID"[>]*>/ As que si encuentras esa lnea para! Puedes parar con un break. Luego hay una lnea fea que no nos interesa, la ignoramos con un web.readlineque lee la lnea y salta a la siguiente. A partir de aqu las lneas contienen los ttulos de las pelis entre las etiquetas <option> y </option>. En realidad no, puede que haya alguna lnea en blanca o que al webmaster se le ocurra meter un comentario por ah, as que tenemos que asegurarnos que la lnea cumpla la siguiente expresin regular: /<option[>]*>.+<option>/i Ya tenemos la lnea que nos interesa, ahora deshagmonos de las etiquetas feas que rodean los ttulos: linea.gsub( /<?[>]+>/i, "" ) Eso indica: sustituye todo lo que empiece por un < seguido de una /, o no, seguido de cualquier carcter que no sea un >, una o ms veces, seguido de un > por una cadena vaca. Cuanto con tan poco, verdad? Si al nal va a ser que las expresiones regulares molan y todo. Por si an quedaran espacios al principio o saltos de lnea los eliminamos con el mtodo strip. Qu hacemos con el ttulo ahora? Pues se lo tiramos a un bloque y que haga l lo que quiera, y tambin lo metemos en una lista por si alguien los quiere todos juntitos. Todo junto sera algo as:

William Viana y Andreu Belmonte pelis_en_cartelera.rb


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 r e q u i r e openu r i def b u s c a r T i t u l o s web = open ( " h t t p : / /www. n e o c i n e . e s / i n d e x . php ? s=c a r t e l e r a&i d=7" ) lista_pelis = [] web . e a c h _ l i n e do | l i n e a | break i f l i n e a . match ( /< s e l e c t name=" p e l i c u l a I D "[^ >] > / i ) end web . r e a d l i n e web . e a c h _ l i n e do | l i n e a | break i f l i n e a . match ( /<\/ s e l e c t >/ i ) i f l i n e a . match ( /<o p t i o n [^>]>.+<\/ o p t i o n >/ i ) t i t u l o = l i n e a . gsub ( /<\/?[^>]+>/ i , " " ) t i t u l o . strip ! yield t i t u l o l i s t a _ p e l i s << t i t u l o end end return l i s t a _ p e l i s end b u s c a r T i t u l o s { | t i t u l o _ p e l i | puts t i t u l o _ p e l i }

26

Qu estpido! Para eso miro directamente la web que est todo ms bonito. Bueno, ya haremos algo ms interesante con los ttulos de las pelis, de momento pasemos al siguiente captulo.

Un lenguaje con clase

5.1

Clases . . . . 5.1.1 Acceso . . 5.1.2 Herencia . 5.2 Mdulos . . . 5.3 Mixins . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . .

. . . . .

. . . . .

. 28 . . 31 . . 32 . 33 . 33

27

William Viana y Andreu Belmonte

28

5.1

Clases

Vayamos al grano. La denicin de la clase va entre las palabras class y end. El nombre de la clase ha de empezar por maysculas. Los constructores de una clase se llaman initialize. Los atributos del objeto empiezan por una @ y los atributos de la clase por @@.
1 c l a s s Persona 2 def i n i t i a l i z e 3 @nombre = " Pepeeee " 4 @dni = " 12345789A" 5 @mail = " pepeeee@pepe . com " 6 @ l o g i n = " pepe " 7 @ c h i s t e = " Mi j e f e me e n c a r g o i r a B a r c e l o n a para . . . " 8 end 9 10 def c o n t a r C h i s t e 11 @chiste 12 end 13 end

Para acceder desde fuera de la clase a sus atributos para lectura has de denir un mtodo con el mismo nombre que el atributo. Si quieres modicar el valor de los atributos desde fuera has de denir mtodos que tengan el mismo nombre que el atributo seguido de un smbolo =. La denicin de la clase sigue abierta, por eso podemos hacer:
1 c l a s s Persona 2 def nombre 3 @nombre 4 end 5 def l o g i n =( u n l o g i n ) 6 @nombre = un_nombre 7 end 8 end

Ahora tenemos el constructor que habamos denido antes ms los nuevos mtodos. Afortunadamente hay una forma abreviada de hacerlo.

William Viana y Andreu Belmonte

29

1 c l a s s Persona 2 a t t r _ r e a d e r : nombre , : d n i 3 attr_writer : login 4 a t t r _ a c c e s s o r : mail , : c h i s t e modificacion 5 end

#podemos a c c e d e r para l e c t u r a #e s l o mismo que e l metodo l o g i n= de a n t e s #podemos a c c e d e r para l e c t u r a y

Te acuerdas de los rangos? Puedes denir tus propios tipos de datos y poder crear rangos con ellos. Lo nico que hace falta es que denas un mtodo succ que acte de una manera apropiada, incluir el mdulo Comparable y denir el mtodo <=>. WTF! Incluir un moqu dentro de una clase? Bueno, por ahora saber que al hacerlo y teniendo denido el mtodo <=> de gratis nuestra clase gana los mtodos <, >, <=, >=, ===, == y algunos ms. Ya veremos por qu, ahora veamos todo esto en prctica. dia_semana.rb
1 2 c l a s s DiaSemana 3 Dias_semana = [ " l u n e s " , " martes " , " m i e r c o l e s " , " j u e v e s " , " v i e r n e s " , \ 4 " sabado " , " domingo " ] 5 i n c l u d e Comparable 6 7 a t t r _ r e a d e r : numdia 8 def i n i t i a l i z e ( d i a ) 9 i f Dias_semana . i n c l u d e ? d i a 10 @numdia = Dias_semana . i n d e x ( d i a ) 11 else 12 r a i s e ArgumentError , " Dia no v a l i d o " 13 end 14 end 15 16 def <=>(o t r o d i a ) 17 @numdia <=> o t r o d i a . numdia 18 end 19 20 def succ 21 DiaSemana . new ( Dias_semana [ @numdia . succ % 7 ] ) 22 end

William Viana y Andreu Belmonte


23 24 def to_s 25 Dias_semana [ @numdia ] 26 end 27 end 28 29 i f $0 == __FILE__ 30 l a b o r a l = DiaSemana . new ( " l u n e s " ) . . DiaSemana . new ( " v i e r n e s " ) 31 hoy = DiaSemana . new ( " domingo " ) 32 33 i f l a b o r a l === hoy 34 p u t s "#{hoy } e s un d i a l a b o r a l " 35 else 36 p u t s "#{hoy } no e s un d i a l a b o r a l " 37 end 38 39 l a b o r a l . each { | d i a | p r i n t "#{d i a } " } 40 end $ ruby diasemana . rb domingo no e s un d i a l a b o r a l l u n e s martes m i e r c o l e s j u e v e s v i e r n e s $

30

El constructor lo primero que hace es comprobar si se le ha pasado un da de la semana vlido: lo comprueba mirando si est en el array Dias_semana con el mtodo include?. Si est almacena la posicin que ocupa el da en el array (equivale a guardar el da en formato numrico empezando con lunes = 0). Si no est lanza una excepcin de tipo ArgumentError con el mtodo raise. El mtodo <=> (tambin conocido como nave espacial) compara dos objetos y devuelve -1 si el primero es menor que el segundo, 0 si son iguales o 1 si el segundo es menor que el primero. Eres bastante mayorcito para saber que hace el mtodo succ El mtodo to_s sirve para poder imprimir nuestro objeto por pantalla. La lnea 29 es un truco para saber si el programa ha sido ejecutado directamente (til si lo queremos probar). Cmo puedes ver en la lnea 30 una instancia de nuestra clase se crea con el nombre de la clase seguido de la palabra new y los argumentos que recibe el constructor entre parntesis. Las clases pueden tener mtodos de la clase. Un mtodo de una clase no est asociado a un objeto de esa clase, sino a la propia clase. Para llamarlo se hace con el nombre de la clase seguido de :: o . y el nombre del mtodo.

William Viana y Andreu Belmonte La clase File por ejemplo tiene algunos mtodos de clase:
1 File : : exists ? 2 F i l e : : chmod 3 F i l e : : rename #comprueba s i un f i c h e r o e x i s t e #cambia l o s p e r m i s o s de un f i c h e r o s #renombra un f i c h e r o

31

Denir mtodos de una clase se hace de la misma forma: con el nombre de la clase seguido de :: o . y el nombre del mtodo. 5.1.1 Acceso

Al igual que otros lenguajes orientados a objeto como Java o C++ tambin se puede denir en Ruby el control de acceso a una clase. Los modos de acceso son los usuales:
1 c l a s s Foo 2 3 def i n i t i a l i z e #por d e f e c t o e s p r i v a d o 4 ... 5 end 6 7 private #s o l o a c c e s i b l e d e s d e d e n t r o d e l o b j e t o 8 def bar 9 ... 10 end 11 p u b l i c #a c c e s i b l e d e s d e f u e r a d e l o b j e t o 12 def f o o 13 ... 14 end 15 p r o t e c t e d #p r i v a d o para e l e x t e r i o r p e r o a c c e s i b l e a l a s c l a s e s que heredan 16 def f o o b a r 17 ... 18 end 19 20 #Tambien s e puede d e f i n i r e l c o n t r o l de a c c e s o d e s p u e s de d e f i n i r l o s metodos 21 p r i v a t e : bar 22 p u b l i c : foo 23 p r o t e c t e d : f o o b a r 24

William Viana y Andreu Belmonte


25 end

32

5.1.2 Como curiosidad, todos las clases que denas por defecto heredan de una clase padre llamada Object con algunos mtodos tiles que puedes sobreescribir y a veces es recomendable que lo hagas. Cuando instancias tu nueva clase con el mtodo new, ests llamando al mtodo new de la clase Object quien luego le pasa al mtodo initialize de tu clase todos los argumentos que le han pasado a l.

Herencia

Heredar es sencillo.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 class Peli def i n i t i a l i z e ( t i t u l o , d i r e c t o r , d u r a c i o n , r e p a r t o ) @titulo = t i t u l o @director = director @duracion = d u r a c i o n @reparto = r e p a r t o end def to_s " T i t u l o : #{@ t i t u l o }\n "+\ " D i r e c t o r : #{@ d i r e c t o r }\n "+\ " Reparto : #{@reparto }\n "+\ " Duracion : #{@duracion }\n " end end c l a s s Dvd < P e l i def i n i t i a l i z e ( t i t u l o , d i r e c t o r , d u r a c i o n , r e p a r t o , p r e c i o , n _ d i s c o s ) super ( t i t u l o , d i r e c t o r , d u r a c i o n , r e p a r t o ) @precio = p r e c i o @numero_discos = n _ d i s c o s end def to_s super + " P r e c i o : #{@ p r e c i o }\n "+\ " Numero de d i s c o s : #{@numero_discos }\n " end end

La clase Dvd es una clase ha de la clase Peli. Los mtodos de la clase Dvd, al llamarse igual, sobreescriben los mtodos heredados pero con el mtodo super dentro de un mtodo se llama al mtodo del mismo nombre de la

William Viana y Andreu Belmonte clase padre. Ruby no soporta herencia mltiple pero lo solventa con algo llamado Mixins, que veremos dentro de nada.

33

5.2

Mdulos

Un mdulo es algo parecido a una clase pero ms sencillo. Se utiliza para agrupar cosas que tienen relacin pero que no forman una clase de manera natural. Dentro de un mdulo puedes tener mtodos, variables o clases. Para acceder a algo de un mtodo se utiliza el operador ::. De hecho has estado utilizando un mdulo todo ese rato sin darte cuenta. Los mtodos print, puts y gets pertenecen al mdulo Kernel y deberas estar llamndolos como Kernel::print, Kernel::puts o Kernel::gets, pero como son mtodos muy utilizados el intrprete de Ruby los busca automticamente en el mdulo Kernel y por eso puedes omitirlo y simplemente poner puts.

5.3

Mixins

Un mixin, del ingls mezcla, no es ms que una clase con un mdulo dentro. Tienes una clase, le metes un mdulo, ya tienes un mixin. Dentro de una clase puedes meter cuantos mdulos te apetezca y sta heredar todo lo que tena el mdulo. Los mdulos dentro de una clase se comportan como si de una clase padre se trataran. Antes hemos creado un mixin con el ejemplo de la clase DiaSemana. Incluimos el mdulo Comparable y ganamos un montn de mtodos gratis, slo haba que cumplir una condicin, tener denidos los mtodos <=> y succ, ya que Comparable asume que la clase que lo hereda los tiene denidos.

Si no lo apunto se me olvida

6.1 6.2 6.3

La clase File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Bienvenido al mundo falible . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Qu voy a ver en el cine? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

35 35 36

34

William Viana y Andreu Belmonte

35 Bueno, trabajar con cheros en Ruby es muy sencillo, no quera incluir un captulo entero para ello pero tena que contarlo en algn lado. Y cmo me quedar muy cortito tambin incluyo un poco de tratamiento de excepciones y un ltimo ejercicio caero.

6.1

La clase File

Veamos todo sobre la prctica


1 #Leer 2 f i c h = F i l e . new ( " f i c h e r o " , " r " ) #e l segundo argumento e s e l modo de a p e r t u r a . 3 f i c h . e a c h _ l i n e { | l i n e a | p u t s l i n e a } #r e c o r r e e l f i c h e r o l i n e a a l i n e a 4 5 #o p c i o n a l m e n t e p u e d e s u s a r 6 fich . readline #que l e e una l i n e a y s e s i t u a para l e e r l a s i g u i e n t e 7 l i s t a = f i c h . r e a d l i n e s #d e v u e l v e un a r r a y de l i n e a s 8 cadena = f i c h . r e a d #d e v u e l v e una cadena con t o d o e l t e x t o d e l f i c h e r o 9 10 #E s c r i b i r 11 f i c h = F i l e . new ( " f i c h e r o " , "w" ) #a b r e e l f i c h e r o para e s c r i b i r 12 f i c h << " Hola mundo\n " 13 f i c h . c l o s e #c i e r r a e l f i c h e r o 14 15 #tambien p u e d e s u s a r : 16 f i c h . p u t s " Hola mundo " 17 f i c h . p r i n t " Ruby mola " 18 19 #Otra forma de h a c e r l o 20 F i l e : : open ( " f i c h e r o " ) . e a c h _ l i n e do | l i n e a | 21 #p r o c e s a d o 22 end 23 #Abre e l f i c h e r o , l o p r o c e s a en e l b l o q u e y a l s a l i r l o c i e r r a

6.2

Bienvenido al mundo falible

Cmo todo lenguaje moderno Ruby tiene un tratamiento de excepciones moderno. Para hacerlo encierras el cdigo susceptible de lanzar una excepcin a partir de la palabra begin, capturamos la excepcin con la palabra rescue

William Viana y Andreu Belmonte

36 seguida del tipo de excepcin. Si el bloque de cdigo es susceptible de lanzar diferentes tipos de excepciones se puede incluir un rescue para cada una. En el rescue es dnde tratas la excepcin. Puede hacer que se vuelve a ejecutar el cdigo del begin con un retry o simplemente lanzar tu una excepcin con raise.
1 begin 2 f i c h = F i l e . new ( " f i c h e r o " ) 3 f i c h . each_line { | l i n e a | puts l i n e a } 4 fich . readline 5 rescue EOFError 6 r a i s e EOFError , " s e ha a l c a n z a d o e l f i n a l d e l f i c h e r o " 7 end

ri es un programa que muestra documentacin sobre mtodos, clases y mdulos de Ruby. Es bastante fcil de usar. ri palabra_clave

6.3

Qu voy a ver en el cine?

Soy una persona un poco manitica y normalmente antes de ir al cine compruebo la nota que tiene la pelcula en el imdb. Ahora, estara bien tener una aplicacin que me bajara la cartelera del cine al que voy y que me ordenara las pelis segn sus notas, as puedo decidir que peli quiero ver. Te propongo como ejercicio que lo hagas, ya hemos visto antes como bajar la cartelera de los Neocine, mitad de la faena hecha, te recomiendo que lo metas en un mdulo y lo guardes en un chero que se llame por ejemplo neocine_parser.rb. Ahora con cada ttulo de una peli tendrs que bajar informacin sobre la pelcula, cmo no hay imdb en castellano, usaremos lm-anity que tambin est muy bien. Bsicamente slo tienes que parsear la web. Para buscar informacin en lm-anity usa esta uri: http://www.lmanity.com/es/search.php?stext=titulo_peli&stype=title. Dnde pone titulo_peli sustituyes por el ttulo de la peli que quieres buscar y ten en cuenta que por ejemplo los espacios en blanco los tendrs que sustituir por %20 y los carcteres con acentos por sus respectivos cdigos. Vas a tener que buscar algo de informacin, es un buen momento para aprender a usar ri para buscar en la documentacin de Ruby. Suerte :P Bueno, vale, no te voy a dejar tan tirado, colgar cuando me apetezca una solucin y la pondr aqu http://www.aditel.org/~wviana/ruby/Cartelera.tar.gz

Qt4-Ruby

7.1 7.2

Introduccin . . . . . . . . . . . . . . . . . . . . . Estructura de un interfaz . . . . . . . . . . . . . . 7.2.1 SignalnSlots: Connecting Peoples objects . . . 7.3 Diseo del interfaz: Designer-qt . . . . . . . . . 7.4 Implementacin de la funcionalidad del interfaz 7.5 Aplicacin principal . . . . . . . . . . . . . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . .

. . . . . .

. . . . . .

. 38 . 38 . . 39 . 40 . 44 . 45

37

William Viana y Andreu Belmonte

38

7.1

Introduccin

Qt es una biblioteca multiplataforma para desarrollar interfaces grcas de usuario. Fue creada por la compaa noruega Trolltech. Qt es utilizada en KDE, un entorno de escritorio para sistemas como linux o FreeBSD, entre otros. Utiliza el lenguaje de programacin C++ de forma nativa. Qt4-ruby son los binding de Qt4 para ruby. Permite realizar aplicaciones grcas utilizando dichas libreras pero utilizando nuestro lenguaje de programacin favorito ruby ;). El proceso se dividir bsicamente en dos etapas. En la primera de ellas disearemos como ser nuestra aplicacin visualmente: como le mostraremos por pantalla al usuario los datos y como podr introducirlos l. En una segunda fase deniremos como interactuar con cada uno de los elementos y como interactuarn los elementos entre s. Programming isnt about what you know; its about what you can gure out. As long as you know where to nd out the things you forgot, youre doing just ne. Chris Pine El objetivo nal de este documento no es ensear como trabajar con las Qt, sino proporcionar los conocimientos y las herramientas necesarias para poder utilizarlas con ruby y describir un breve ejemplo de como hacerlo.

7.2

Estructura de un interfaz

Qt est estructurado en clases. Hay clases que estn en lo alto de la jerarqua y hay otras que heredan de estas. No vamos a entrar a explicar demasiado detalladamente como se estructura, pero a grandes rasgos (y teniendo en cuenta los cambios que ha habido con la nueva versin) las clases que ms comnmente usaremos las podemos dividir en estos grandes grupos: QWidget:: Clase base para crear varios tipos de ventana QMainWindow:: Ventana principal de aplicacin, posiblemente con mens, barras de herramientas, barras de estado,. . . QDialog:: Ventana de dialogo para tareas simples y a corto trmino: dilogos de error, abrir archivos, seleccionar color,. . . QLayout:: clase base para el manejo de geometras, redimensionamiento automtico para componer dilogos ms complejos: QBoxLayout:: de sta clase heredan QHBoxLayout y QVBoxLayout para construir diseos en horizontal o vertical. QGridLayout:: til para construir diseos en forma de cuadrcula QStackedLayout:: para crear un conjunto de widgets de los que solo se muestra uno cada vez

William Viana y Andreu Belmonte De QWidget tambin heredan las clases de de los elementos bsicos de un interfaz como pueden ser: QComboBox:: Lista emergente de datos, que puede ser editable para introducir nuevos elementos QLabel:: para mostrar texto e imgenes QPushButton botn QTextBrowser:: Caja de edicin de texto con tags HTML 7.2.1 Callback: es un puntero a una funcin, que le pasas a una funcin de tratamiento de un determinado evento. Cuando ocurre un evento en un objeto, la funcin de tratamiento llama a nuestra funcin callback. Tambin podemos conectar seales con seales: cuando se emite una seal, automticamente sta hace que se emita la segunda SignalnSlots: Connecting Peoples objects

39

Es posiblemente la mayor diferencia entre Qt y los otros toolkits de programacin grca. Mientras la mayora de otros entornos utilizan los callbacks en Qt usaremos los Signals y los Slotss. Una Signal es emitida cuando un determinado evento ocurre, los objetos de Qt disponen de numerosos eventos que generarn su correspondiente seal. Un Slot es una funcin que se llama como respuesta a una determinada seal (pero que tambin puede ser llamada directamente desde nuestro cdigo). Lo que tenemos que hacer es conectar cada seal que queremos tratar con un slot o incluso varios si fuera necesario. . Las Seales y los Slots no saben si estn conectadas o si hay alguien conectado a ellas lo que garantiza que estemos creando componentes independientes entre s. Tomemos como ejemplo un botn instanciado de la clase Qt::PushButton. Las acciones que podemos realizar con un botn son:

Evento
Presionar el botn Dejar de presionarlo Pulsarlo: Presionar+Dejar

Seal emitida
pressed released clicked

Si queremos que nuestra aplicacin trate el botn cuando sea pulsado, deberemos conectar su seal con un slot que nosotros denamos:
\ t e x t i t {Qt } : : Obj ect . c o n n e c t ( @Boton , SIGNAL( c l i c k e d ( b o o l ) ) , s e l f , SLOT( f u n c i o n ( ) ) )

William Viana y Andreu Belmonte Para el caso anterior, con denir una funcin con nombre on_Boton_Clicked() hubiera sido suciente.

40 A la hora de la verdad no ser necesario realizar este proceso manualmente. Por un lado, cuando queramos conectar unas seales con otras lo haremos en el propio designer-qt4 de forma grca. Y por otro lado, para conectar las seales con nuestras funciones, utilizaremos una nomenclatura determinada y el propio sistema nos las conectar automticamente.

7.3

Diseo del interfaz: Designer-qt

Para poder disear nuestro interfaz podramos crear a mano deniendo en nuestro cdigo los distintos elementos indicando sus propiedades y coordenadas. Pero ser mucho ms fcil si utilizamos la aplicacin que nos proporcionan las propias Qt, el QtDesigner.

William Viana y Andreu Belmonte Las partes principales del interfaz que usaremos son: Qt Desinger (ventana principal) ah tenemos todos los elementos para poder arrastrarlos a nuestra aplicacin Property Editor editor de propiedades del elemento que tengamos seleccionado Object Inspector lista jerrquica con las clases que estamos usando en nuestro interfaz Signal/Slot Editor podremos editar las conexiones que tengamos y aadir nuevas manualmente Inicialmente deberemos seleccionar que tipo de venta queremos crear, normalmente Main Window o Widget

41

A la hora de crear nuestras aplicaciones ser interesantes que organicemos los elementos en layouts para que se redimensionen automticamente con la ventana.

En el propio desginer podremos denir que seales queremos conectar, como se ha visto antes se pueden relacionar varios tipos de seales y eventos, pero en este caso, solo lo utilizaremos para relacionar elementos entre s. presionando F4 entraremos en modo Edit Singals/Slots, el funcionamiento es Drag&Drop1 , seleccionamos un elemento de el que queremos capturar una seal y los soltamos en otro al que le queremos activar otra. Nos aparecer una ventana de dialogo donde deberemos seleccionar concretamente las seales que queremos conectar (como se muestra en la gura).
1

arrastrar y soltar

William Viana y Andreu Belmonte

42

Generar el cdigo Es recomendable utilizar una nomenclatura ms o menos formal para cada tipo de chero. Por ejemplo: ui_nombreinterfaz.rb para la especicacin del interfaz nombreinterfaz.rb para la parte de implementacin que veremos ms adelante Una vez creado el interfaz lo guardaremos como chero .ui, esto es, un chero en XML con la especicacin de nuestra ventana. Tendremos que transformarlo en cdigo para poderlo utilizar en nuestra aplicacin. Y para ello utilizaremos la herramienta rbuic que nos proporcionan los propios bindings de qt4-ruby. La forma de uso es muy simple:
$ r b u i c form . u i > ui_form . rb $

Opcionalmente le podemos pasar el parmetro -x que nos generar el cdigo necesario para poder cargar directamente la aplicacin desde la linea de comandos y comprobar que est todo correcto. Como ejemplo el cdigo que correspondera a la siguiente ventana:

William Viana y Andreu Belmonte ui_form.rb


1 c l a s s Ui_Form 2 attr_reader : l a be l 3 a t t r _ r e a d e r : pushButton 4 5 def s e t u p U i ( form ) 6 form . setObjectName ( " form " ) 7 @ l a b e l = Qt : : L a b e l . new ( form ) 8 @ l a b e l . setObjectName ( " l a b e l " ) 9 @ l a b e l . setGeometry ( Qt : : Rect . new ( 1 1 0 , 6 0 , 1 9 1 , 9 1 ) ) 10 @ l a b e l . setFrameShape ( Qt : : Frame : : Box ) 11 @pushButton = Qt : : PushButton . new ( form ) 12 @pushButton . setObjectName ( " pushButton " ) 13 @pushButton . setGeometry ( Qt : : Rect . new ( 1 7 0 , 2 1 0 , 8 0 , 2 7 ) ) 14 r e t r a n s l a t e U i ( form ) ; 15 s i z e = Qt : : S i z e . new ( 4 4 5 , 2 9 6 ) 16 s i z e = s i z e . expandedTo ( form . minimumSizeHint ( ) ) 17 form . r e s i z e ( s i z e ) 18 19 Qt : : MetaObject . connectSlotsByName ( form ) 20 end # s e t u p U i 21 22 def r e t r a n s l a t e U i ( form ) 23 form . setWindowTitle ( Qt : : A p p l i c a t i o n . t r a n s l a t e ( " Form " , " Form " , n i l , Qt : : A p p l i c a t i o n : : UnicodeUTF8 ) ) 24 @ l a b e l . s e t T e x t ( Qt : : A p p l i c a t i o n . t r a n s l a t e ( " Form " , " TextLabel " , n i l , Qt : : A p p l i c a t i o n : : UnicodeUTF8 ) ) 25 @pushButton . s e t T e x t ( Qt : : A p p l i c a t i o n . t r a n s l a t e ( " Form " , " PushButton " , n i l , Qt : : A p p l i c a t i o n : : UnicodeUTF8 ) ) 26 end # r e t r a n s l a t e U i 27 28 end 29 module Ui 30 c l a s s Form < Ui_Form 31 end 32 end # module Ui

43

William Viana y Andreu Belmonte

44

7.4
Para poder acceder a las propiedades de cualquiera de los elementos del interfaz, tendremos que hacerlo a travs de dicha variable, por ejemplo @ui.pushButton corresponder al objeto que contiene el botn.

Implementacin de la funcionalidad del interfaz

Ya tenemos nuestro interfaz. Ahora deberemos de conectar los widgets con las funciones de nuestra aplicacin. En el chero del interfaz tenemos implementado un modulo Ui que incluye la clase Form. Crearemos un nuevo chero en el que tendremos que incluir la denicin del interfaz, el mtodo initialize (el constructor) deber crear un objeto de la clase que corresponder a una instancia de Ui::Form. form.rb
1 r e q u i r e ui_form . rb 2 3 c l a s s Form < Qt : : Widget 4 s l o t s on_pushButton_released ( ) 5 6 def i n i t i a l i z e ( p a r e n t=n i l ) 7 super ( p a r e n t ) 8 @ui=Ui : : Form . new 9 @ui . s e t u p U i ( s e l f ) 10 end 11 12 def on_pushButton_released ( ) 13 @ui . l a b e l . s e t T e x t ( " h o l a " ) 14 end 15 end

Tenemos denido un slot, que corresponde con la funcin on_pushButton_released():


nombre del widget

on_ pushButton _

released
evento capturado

Siguiendo este formato tendremos nuestras seales y slots conectados ya que en el constructor se ejecuta el mtodo connectSlotsByName. Para consultar informacin referente a los mtodos y clases, disponemos del comando rbqtapi equivalente al ri normal de ruby Como vemos capturar el evento de pulsado del botn pushButton, y lo que har es cambiar el texto del label mediante el mtodo setText propio de la clase Qt::Label. En ocasiones no nos valdr con la denicin por defecto o querremos denir nuestras seales a mano, lo normal ser hacerlo en el constructor:

William Viana y Andreu Belmonte

45

Qt : : Obj ect . c o n n e c t ( @ui . l i s t a , SIGNAL( i t e m C l i c k e d ( QListWidgetItem ) ) , s e l f , SLOT( o n _ l i s t a _ i t e m D o u b l e C l i c k e d ( QListWidgetItem ) ) )

7.5

Aplicacin principal

Por ltimo crearemos un nuevo chero en el que incluiremos nuestra nueva clase Form. De esta forma, podremos aadir en nuestra aplicacin todas los interfaces que sean necesarias. En este cdigo simplemente crearemos una instancia de aplicacin (lnea 4) y le incluiremos un nuevo objeto de nuestra ventana (lnea 5): main.rb
1 r e q u i r e form . rb 2 3 i f $0 == __FILE__ 4 a = Qt : : A p p l i c a t i o n . new (ARGV) 5 u = Form . new 6 u . show 7 a . exec 8 end

Dice la leyenda que se empieza por documentar y se acaba por implementar

8.1 8.2 8.3

Introduccin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . SimpleMarkup o yo solo s HTML, como se juega a esto? . . . . . . . . . . . . . y ahora?. . . ejecucin sobre nuestro cdigo . . . . . . . . . . . . . . . . . . . . . . .

47 47 50

46

William Viana y Andreu Belmonte

47

8.1
A la hora de documentar no hay que perder de vista, que lo que queremos hacer no es explicar que hace cada lnea de nuestro cdigo, sino cual es el cometido de cada uno de sus partes: que hacen nuestros mtodos, para que sirve nuestra nueva clase, . . . Cuando pasado un tiempo queramos recuperar un proyecto, o cuando queramos pasrselo a otra persona agradeceremos haber realizado algunas anotaciones.

Introduccin

En ruby existen dos formas de generar documentacin a partir del propio cdigo: rdoc y RDtool (tambin disponible para otros lenguajes). Mientras que rdoc es bsicamente un documentador de cdigo, RDtool es un lenguaje de marcado que no entiende nada de cdigo. Con RDtool necesitas introducir etiquetas del tipo =begin/=end. En cambio rdoc parsea los cheros de cdigo fuente extrayendo las clases, mdulos, atributos y deniciones de mtodos automticamente. Osea que rdoc es el documuentador de cdigo para los vagos ;), pero que eso no os confunda, tambin dispone de un lenguaje propio en caso de que queramos ser ms descriptivos a la hora de trabajar

8.2

SimpleMarkup o yo solo s HTML, como se juega a esto?

Bsicamente rdoc ir pillando todos los comentarios justamente anteriores a vuestras clases/mdulos/mtodos y lo aadir a la documentacin. si queremos que quede ms bonito ser interesante aadir ciertas etiquetas. Para consultar el cdigo y el resultado de los ejemplos que se irn mostrando se puede acceder a la siguiente direccin: http://www.aditel.org/~andreu/ruby/rdoc_example/ verbatim Todas las lineas que comiencen a la misma distancia del margen sern tratadas como prrafos, pero si le aadimos un nivel de identacin nos lo meter como verbatim, es decir, no procesar las directivas que encuentre dentro.
1 #Esto e s una l i n e a de c o m e n t a r i o 2# p e r o a q u i no t r a t a r e m o s l o s t a g s que 3# veremos mas a d e l a n t e , como puede s e r : 4# negrita 5 c l a s s Verbatim 6 end

Formateo del texto Tenemos tres tipos de letra: negrita, cursiva y mquina de escribir. Tenemos dos formas de etiquetar el texto: rodeando la palabra con smbolos espaciales (*,+,_) o utilizando tags del tipo HTML:

William Viana y Andreu Belmonte

48

1 # <b>n e g r i t a </b >: 2 # \<b>n e g r i t a </b> 3 # \ n e g r i t a 4 # <em>c u r s i v a </em> 5 # \<em>c u r s i v a </em> 6 # \ _cursiva_ 7 # <t t >maquina de e s c r i b i r </ t t > 8 # \< t t >maquina de e s c r i b i r </ t t > 9 # \+maquina de e s c r i b i r+ 10 c l a s s Formateo_del_texto 11 end

Listas y descripciones Las listas ya aparecan en el apartado anterior, podemos utilizar varios tipos:
1 # un o para l i s t a s i m p l e 2 # un numero s e g u i d o de un punto 3 # para una l i s t a numerada 4 # 1 . uno 5 # 2 . dos 6 # 3. tres 7 # una l e t r a s e g u i d a de un punto 8 # para numerar con l e t r a s 9# a. a 10 # b . be 11 # c . ce 12 c l a s s L i s t a s _ y _ d e s c r i p c i o n e s 13 end

Comentarios comentados (???) Si en ocasiones aadimos anotaciones con comentarios internos para uno mismo (tu ya me entiendes), es interesante que luego no aparezca en la documentacin nal. . . no queda bonito. Lo delimitaremos con # y #++:
1 #Esta c l a s e e s muy i m p o r t a n t e

William Viana y Andreu Belmonte


2# 3 #j a j a j a p e r o s i no v a l e pa na 4 #p e r o bueno 5# ++ 6 #no hay que d e j a r de u s a r l a 7 c l a s s Comentarios 8 end

49

Titulos En este ejemplo podemos ver como hacer titulo con fuentes de tamao ms grande. Faros en el resultado nal, observad que los datos que devuelve la funcin con el yield, nos aparecen como datos de entrada de la funcin en formato de bloque.
1 #=T i t u l o 1 2 #Esto e s t e x t o de e s t e p a r r a f o 3# 4# ==T i t u l o 2 5 #Texto d e l o t r o 6# 7# 8 class Titulos 9 def each 10 @datos . each do | dato | 11 yield dato 12 end 13 end 14 15 def [ ] ( i n d i c e ) 16 return @datos [ i n d i c e ] 17 end 18 end

William Viana y Andreu Belmonte

50

8.3

y ahora?. . . ejecucin sobre nuestro cdigo

Debemos ejecutar el comando rdoc indicando el directorio donde est nuestra documentacin y el formato de salida (entre otro parametros). En nuestro caso ser interesante utilizar el parametro -c para indicarle que encoding hemos usado en nuestro cdigo seguramante:
a n d r e u @ a r t u r i t o : ~ / work / $ r d o c c u t f 8 example . rb a n d r e u @ a r t u r i t o : ~ / work / $ r d o c c i s o 8 8 5 9 15 example . rb

En cuanto a formatos de salia, dispone de ltros para HTML, XML, chm (en windows) y lo que es ms interesante, dispone de un ltro para generar documentacin que despus utilizar el ri. Por defecto nos generar en el subdirectorio doc del proyecto, la documentacin en html. Si queremos que nos genere la documentacion para usar con ri, simplemente debemos de pasarle el parametro -r
a n d r e u @ a r t u r i t o : ~ / work / $ r d o c c u t f 8 r example . rb example . rb : G e n e r a t i n g HTML . . . Files : Classes : Modules : Methods : Elapsed : 1 0 0 3 0.339 s ...

a n d r e u @ a r t u r i t o : ~ / work / $

Una vez generada, la almacenar en nuestro home y podremos consultarla como si fuera una clase/mtodo del propio sistema:
a n d r e u @ a r t u r i t o : ~ / work / $ r i Verbatim C l a s s : Verbatim Esto e s una l i n e a de c o m e n t a r i o p e r o a q u i no t r a t a r e m o s l o s t a g s que veremos mas a d e l a n t e , como puede s e r : <b>n e g r i t a </b> a n d r e u @ a r t u r i t o : ~ / work / $

Material relacionado

Ruby
Pgina ofcial de Ruby - http://www.ruby-lang.org/es Whys (Poignant) Guide to Ruby - http://poignantguide.net Programming Ruby: The Pragmatic Programmers Guide - http://www.rubycentral.com/book/

QtRuby
Korundum/QtRuby - Ruby-KDE/Qt bindings project - http://rubyforge.org/projects/korundum/ KDE Developers Corner: Ruby bindings - http://developer.kde.org/language-bindings/ruby/index.html Qt Reference Documentation (Open Source Edition) - http://doc.trolltech.com/4.2/

rdoc
rdoc - http://rdoc.sourceforge.net/

51

10

Agradecimientos

Este manual lo hemos escrito para que sirva de material de apoyo para el curso de Ruby/Qt4 que lo podremos dar gracias a ADITEL. Gracias tambin al departamento de lenguajes y sistemas informticos y al departamento de ingeniera y ciencia de computadores de la Universitat Jaume I por subvencionar el curso. Queremos agradecer en particular a nuestros amigos que nos han apoyado y ayudado mientras escribiamos este manual, gracias a lvaro Cuevas por la ayuda con las Qt4, gracias a Ignacio Gil, quien ha sido como un manual A de L TEXpara nosotros, gracias a Antonio Prez con los layouts del Qt-Designer y gracias a Rubn y a Rosa por acojernos en su casa y darnos de comer durante los nes de semana que hemos pasado all escribindolo.

52

11

Sobre este documento

Podrs encontrar una versin electrnica de este documento en la direccin http://www.aditel.org/~wviana/ ruby/manual_ruby.pdf. Esta obra est bajo una licencia Reconocimiento 2.5 Espaa de Creative Commons. Para ver una copia de esta licencia, visite http://creativecommons.org/licenses/by/2.5/es/legalcode.ca o envie una carta a Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.

53

William Viana y Andreu Belmonte

54 El logo de Ruby es copyright(c) 2006 de Yukihiro Matsumoto y se distribuye bajo los trminos de la licencia Share-Alike 2.5 de Creative Commons: http://creativecommons.org/licenses/by_sa/2.5/