Página original: http://pine.fm/LearnToProgram/?Chapter=05
Hasta ahora hemos visto algunos métodos diferentes, puts, gets, entre otros (Pregunta rápida: Escribe todos los métodos que hemos visto hasta ahorita. Son 10! La respuesta esta un poco mas abajo.), pero no hemos hablado acerca de lo que son los métodos. Sabemos que hacen algo, pero no sabemos lo que son.
En realidad eso es lo que son: cosas que hacen algo. Si los objetos (como cadenas, enteros y flotantes) son el sujeto en el lenguaje de Ruby, entonces los métodos son como verbos. Y, al igual que en el Ingles, no puedes tener verbos sin un sujeto. Por ejemplo, avanzar no es algo que sucede sin mas; un reloj (o alguna otra cosa) avanza. En español diríamos “El reloj avanza”. En Ruby diríamos reloj.avanza (asumiendo que el reloj fuera un objeto de Ruby). Los programadores podrían decir que estamos “llamando el método avanzar de reloj” o que “llamamos el método avanzar del reloj“.
¿Supiste la respuesta a la pregunta rápida? Seguramente recordaste los métodos puts, gets y chomp ya que los acabamos de ver. Probablemente también te acordaste de los métodos,to_i, to_f y to_s. Pero, ¿te acordaste de los otros cuatro? No son otros mas que los operadores aritméticos +, -, * y /!
Así que, como decía, cada verbo necesita un sujeto, al igual que cada método necesita un objeto. Es sencillo saber cual es el objeto y cual es el método: el método se encuentra después del punto, como en ejemplo de reloj.avanza o en 101.to_s. Algunas veces, sin embargo, no es tan obvio, como en los métodos aritméticos. Resulta que 5 + 5 es solo un atajo para escribir 5.+ 5. Por ejemplo:
1 2 | puts 'hola '.+ 'mundo' puts (10.* 9).+ 9 |
hola mundo 99
No es muy bonito, así que no lo escribiremos así, sin embargo, es importante entender lo que realmente sucede. (En mi computadora me da una advertencia: warning: parenthesize argument(s) for future version. Aun así el código se ejecuto bien, pero esta diciendo que tuvo problemas al intentar leer lo que quise decir y que use mas paréntesis en el futuro.) Esto también nos enseña mas a mayor profundidad porque podemos hacer ‘cerdo’*5 pero no 5*’cerdo’: ‘cerdo’*5 esta diciendo ‘cerdo‘ se multiplique, pero en 5*’cerdo‘ esta diciendo que 5 se multiplique. ‘cerdo‘ sabe como hacer 5 copias de si mismo y ponerlas todas juntas, sin embargo 5 la va a tener mas difícil haciendo ‘cerdo‘ copias de si mismo y ponerlos juntos.
Y, por supuesto, aun tenemos que explicar puts y gets. ¿Donde estan sus objetos? En ingles, algunas veces puedes dejar fuera el sujeto, por ejemplo, si un villano grita “Muere!”, el sujeto esta implícito en a quien sea que se lo esté gritando. En Ruby, si pongo puts ‘ser o no ser’, lo que realmente estoy diciendo es self.puts ‘ser o no ser’. ¿Que es self? Es una variable especial que apunta al objeto al que te encuentras. Aun no sabemos como estar en un objeto, pero lo sabremos, pero siempre vamos a estar en un gran objeto que es… todo el programa! Y por suerte, el programa tiene unos métodos propios como gets y puts. Observa esto:
1 2 3 | noPuedoCreerQueHayaHechoUnaVariableTanLargaParaApuntaral3 = 3 puts noPuedoCreerQueHayaHechoUnaVariableTanLargaParaApuntaral3 self.puts noPuedoCreerQueHayaHechoUnaVariableTanLargaParaApuntaral3 |
3 3
Si no entendiste todo esto, esta bien. Lo importante de todo esto es saber que todo método esta siendo llamado por un objeto, aun si no tiene un punto enfrente. Si haz entendido eso, estas hecho.
Métodos para cadenas
Aprendamos algunos métodos para cadenas. No tienes que memorizarlos todos, puedes regresar a esta pagina si los olvidas. Solo quiero mostrarte una pequeña parte de lo que pueden hacer las cadenas. De hecho, ni yo puedo recordar la mitad de los métodos para las cadenas, pero eso esta bien, porque hay muchas referencias en internet con listas de los métodos para cadenas con todo y explicación. (Te diré donde encontrarlos al final del tutorial.) La verdad, no quiero saber todos los métodos para las cadenas, es como querer saber todas las palabras en el diccionario. Puedo hablar español bien sin saber todas las palabras del diccionario… y no es esa la función del diccionario? Que no tengas que saber todas las palabras.
Así que, nuestro primer método para cadenas es reverse, que nos da una version invertida de una cadena:
1 2 3 4 5 6 7 8 9 10 | var1 = 'alto' var2 = 'estresado' var3 = 'Puedes pronunciar esta linea al reves?' puts var1.reverse puts var2.reverse puts var3.reverse puts var1 puts var2 puts var3 |
otla odasertse ?sever la aenil atse raicnunorp sedeuP alto estresado Puedes pronunciar esta linea al revés?
Como puedes ver, reverse no invierte la cadena original, solo hace una version invertida de la misma. Por eso es que var1 sigue siendo ‘alto’ aun cuando aplicamos el método reverse en var1.
Otro método para cadenas es length, que nos da el numero de caracteres (incluyendo espacios) en la cadena:
1 2 3 | puts 'Cual es tu nombre completo? nombre = gets.chomp puts 'Sabias que hay ' + nombre.length + ' letras en tu nombre, ' + nombre + '?' |
Cual es tu nombre completo?
Christopher David Pine
#<TypeError: can't convert Fixnum into String>
Algo falló, y parece que sucedio despues de la línea nombre = gets.chomp… Puedes ver el problema? Ve si puedes resolverlo.
El problema es length: nos da un numero, pero queremos una cadena. La solución es sencilla, solo agreguemos to_s (y crucemos los dedos):
1 2 3 | puts 'Cual es tu nombre completo? nombre = gets.chomp puts 'Sabias que hay ' + nombre.length + ' caracteres en tu nombre, ' + nombre + '?' |
Cual es tu nombre completo?
Christopher David Pine
Sabias que hay 22 letras en tu nombre, Christopher David Pine?
No, no lo sabía. Ojo: Ese es el numero de caracteres en el nombre, mas no es el numero de letras (cuentalas). Supongo que podríamos escribir un programa que primero pregunte el primer nombre, luego el segundo nombre, luego el apellido paterno y luego el apellido materno, y entonces sumar esos números… Porque no lo haces?
Ya lo hiciste? Es divertido programar no? Después de algunos capítulos te vas a sorprender de todo lo que puedes hacer.
También hay métodos que nos permiten cambiar la capitalización (mayúsculas y minúsculas) de las cadenas. upcase cambia todas las letras minúsculas a mayúsculas y downcase cambia todas las letras mayúsculas a minúsculas. swapcase invierte la capitalización de las letras en una cadena y finalmente, capitalize que es como downcase, excepto que si el primer caractér de la cadena es una letra, lo cambia a mayúscula.
1 2 3 4 5 6 7 | letras = 'aAbBcCdDeE' puts letras.upcase puts letras.downcase puts letras.swapcase puts letras.capitalize puts ' a'.capitalize puts letras |
AABBCCDDEE aabbccddee AaBbCcDdEe Aabbccddee a aAbBcCdDeE
Como puedes ver en la linea puts ‘ a’.capitalize, el método capitalize solo convierte a mayúscula el primer caractér, no la primera letra. También, como hemos visto anteriormente, estos métodos no cambian la variable letras. No quiero sonar repetitivo, pero creo que es importante entender esto. Hay unos métodos que si cambian el objeto asociado, pero aun no hemos visto ninguno, y no lo haremos por un tiempo.
El ultimo de los métodos que veremos para cadenas es para dar un formato visual. El primero, center, agrega espacios al principio y al final de la cadena para centrarlo. Sin embargo, así como decimos a puts que es lo que queremos que imprima en pantalla, y usamos + para agregarle algo, tenemos que decirle a center que tan ancho es el espacio donde debe de centrar la cadena. Así que si queremos centrar las lineas de un poema, lo que haríamos sería esto:
1 2 3 4 5 6 7 | anchodeLinea = 50 puts( 'Old Mother Hubbard'.center(anchodeLinea)) puts( 'Sat in her cupboard'.center(anchodeLinea)) puts( 'Eating her curds an whey,'.center(anchodeLinea)) puts( 'When along came a spider'.center(anchodeLinea)) puts( 'Which sat down beside her'.center(anchodeLinea)) puts('And scared her poor shoe dog away.'.center(anchodeLinea)) |
Old Mother Hubbard
Sat in her cupboard
Eating her curds an whey,
When along came a spider
Which sat down beside her
And scared her poor shoe dog away.
No estoy seguro si la rima va así, pero me da flojera buscarla. (También quise alinear los .center(anchodeLinea), por eso puse esos espacios de mas en el código. Creo que se ve mejor el código. Los programadores tienen un sentimiento mas fuerte de como se ve mejor en el código. Mientras mas programes, mas vas a desarrollar un estilo propio.)
Hablando de flojera, la flojera no siempre es malo en la programación. Por ejemplo, ¿viste que guardé el ancho del poema en una variable llamada anchodeLinea? Esto es, para si quiero cambiar después el ancho de la linea y hacerlo mas ancho, solo tengo que cambiar esa linea, en vez de ir cambiando cada una. Con un poema muy largo, esto nos puede ahorrar mucho tiempo. Ese tipo de flojera es una virtud en un programador.
Acerca del centrado… puedes haber notado que no se ve tan presentable como lo hubiera hecho un procesador de palabras. Si quisieras un centrado perfecto (y un mejor tipo de letra), tal vez deberías de usar un procesador de palabras. Ruby es una gran herramienta, pero no ninguna herramienta es la herramienta correcta para cada trabajo.
Los otros métodos para dar formato a una cadena son ljust y rjust, que son para alinear a la izquierda (left justify) y alinear a la derecha (right justify). Son similares a center, excepto que estos métodos le agregan espacios a la cadena de la derecha y de la izquierda, respectivamente. Veamos los métodos en acción:
1 2 3 4 5 6 | anchodeLinea = 40 cad = '--> texto <--' puts cad.ljust anchodeLinea puts cad.center anchodeLinea puts cad.rjust anchodeLinea puts cad.ljust (anchodeLinea/2) + cad.rjust (anchodeLinea/2) |
--> texto <--
--> texto <--
--> texto <--
--> texto <-- --> texto <--
Algunas cosas para intentar
- Escribe un programa de Jefe Enojado. Debe de preguntarte de que es lo que quieres. Cualquiera que sea la respuesta, el Jefe Enojado debe de gritartela a ti y despedirte. Por ejemplo, si le dices Quiero un aumento., debe de responderte QUE QUIERES DECIR CON "QUIERO UN AUMENTO."?!? ESTAS DESPEDIDO!!
- Y aquí hay algo mas para que juegues un poco mas con center, ljust y rjust. Escribe un programa que te despliegue una Tabla de Contenidos como esta:
Tabla de Contenidos Capitulo 1: Numeros pagina 1 Capitulo 2: Letras pagina 72 Capitulo 3: Variables pagina 118
Matemática Avanzada
(Esta sección es totalmente opcional. Se asume que se tiene conocimiento de un grado avanzado de matemáticas. Si no estas interesado te puedes ir directamente al Control de Flujo sin ningún problema. Sin embargo, una vista rápida a los Números Aleatorios puede ser útil.)
No hay, ni de cerca, tantos métodos para números como para cadenas (y aún así no me los se todos). Aquí veremos el resto de los métodos matemáticos, un generador de números aleatorios y el objeto Math, con sus métodos de trigonometría.
Mas aritmética
Los otros dos métodos aritméticos son ** (exponente) y % (modulo). Así que si quieres elevar 5 al cuadrado en Ruby, debes de escribirlo 5**2. También puedes usar flotantes como exponentes, así que, si quieres saber la raíz cuadrada de 5, debes escribir 5**0.5. El método modulo, te da el residuo de una división. Por ejemplo, si dividimos 7 entre 3, tendría 2 con residuo de 1. Veamos como funciona en un programa:
1 2 3 4 5 | puts 5**2 puts 5**0.5 puts 7/3 puts 7%3 puts 365%7 |
25 2.23606797749979 2 1 1
De la ultima linea, aprendimos que un año (no bisiesto) tiene cierto numero de semanas, mas un día. Así que si tu cumpleaños fue un Martes este año, será un Miércoles el próximo año. También se pueden usar flotantes en el método de modulo.
Hay un ultimo método que mencionar antes de ver el generador aleatorio de números: abs. Nos da el valor absoluto de un numero:
1 2 | puts ((5-2).abs) puts ((2-5).abs) |
3 3
Números Aleatorios
Ruby viene con un buen generador de números aleatorios. El método es rand. Si llamamos a rand, sin parámetros, obtendremos un flotante mayor que, o igual a 0.0 y menor que 1.0. Si pones rand y un entero (5 por ejemplo), nos devolverá un entero mayor que, o igual a 0 y menor a 5 (esto nos da cinco posibles números, del 0 al 4).
Veamos rand en acción. (La página original del tutorial genera los números en tiempo real cada que recargas la página.)
1 2 3 4 5 6 7 8 9 10 11 12 | puts rand puts rand puts rand puts(rand(100)) puts(rand(100)) puts(rand(100)) puts(rand(1)) puts(rand(1)) puts(rand(1)) puts(rand(99999999999999999999999999999999999999999999999999999999999)) puts('En el estado del tiempo dijeron que existe un '+rand(101).to_s+'% ') puts('de posibilidades de lluvia.') |
0.485031766917276 0.518411504405089 0.37686171240106 2 9 61 0 0 0 18778163643166246345201376367520329469223063328122921224471 En el estado del tiempo dijeron que existe un 28% de posibilidades de lluvia.
Toma en cuenta que usé rand(101) para obtener unos números del 0 al 100, y que rand(1) siempre devuelve 0. No entender el rango de los posibles valores es el error mas grande que comete la gente con rand, incluso los programadores profesionales, incluso en productos que puedes comprar en las tiendas. Una vez tuve un reproductor de CD, en el que si ponía "Reproducción Aleatoria", tocaba todas las canciones, excepto la ultima. (Me pregunto que hubiera pasado si le hubiera puesto un CD con una sola canción.)
Algunas veces vas a querer que rand te regrese los mismos números aleatorios en diferentes secuencias del mismo programa. (Por ejemplo, una vez estaba usando números aleatorios para crear mundos aleatorios en un juego de computadora. Si encontraba un mundo que me gustara, tal vez quisiera jugarlo de nuevo, o enviarlo a un amigo.) Para hacer esto, necesitas poner una semilla, que puedes hacer con srand. Así:
1 2 3 4 5 6 7 8 9 10 11 12 13 | srand 1776 puts(rand(100)) puts(rand(100)) puts(rand(100)) puts(rand(100)) puts(rand(100)) puts '' srand 1776 puts(rand(100)) puts(rand(100)) puts(rand(100)) puts(rand(100)) puts(rand(100)) |
24 35 36 58 70 24 35 36 58 70
Hará lo mismo cada vez que uses como semilla el mismo numero. Si quieres obtener números diferentes otra vez (lo cual sucede si nunca usas srand), solo escribe srand 0. Esto pone como semilla números raros, usando (entre otras cosas) la hora actual en tu computadora, usando hasta los milisegundos.
El objeto Math
Finalmente, hay que ver el objeto Math.
1 2 3 4 5 6 | puts(Math::PI) puts(Math::E) puts(Math.cos(Math::PI/3)) puts(Math.tan(Math::PI/4)) puts(Math.log(Math::E**2)) puts((1 + Math.sqrt(5))/2) |
3.14159265358979 2.71828182845905 0.5 1.0 2.0 1.61803398874989
Lo primero que debes de haber notado fue la notación de ::. Explicar lo que es un operador de ámbito (que es lo que es) está mas allá del... ámbito de este tutorial. No intento confundirlos. Es mas que suficiente decir que puedes usar Math::PI y funcionará tal y como esperas.
Como puedes ver, Math tiene todo lo que uno puede esperar de una calculadora científica decente. Y como siempre, los flotantes están realmente cerca de ser la respuesta correcta.
Sigamos con los controles de flujo.
Etiquetas: Programación, Ruby, Tutorial








1 comentario → Deja un comentario
Trackback URL
Trackbacks & Pingbacks